muzhiyu-ui 1.0.0 → 1.0.2

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.
package/README.md CHANGED
@@ -1,17 +1,18 @@
1
1
  # MuzhiyuUI 极奢全端组件库
2
2
 
3
- > **MuzhiyuUI** 是一套专为 **UniApp + Vue 3** 打造的全端极奢 UI 组件库。包含 **89+ 生产级高频组件**、**Axios 级拦截器 HTTP 客户端**、**格式化与正则校验工具箱** 以及 **全平台暗黑模式原生适配**。
3
+ > **MuzhiyuUI** 是一套专为 **UniApp + Vue 3** 打造的全端极奢 UI 组件库。包含 **90+ 生产级高频组件**、**Axios 级拦截器 HTTP 客户端**、**格式化与正则校验工具箱**、**TypeScript 全量智能提示** 以及 **全平台暗黑模式原生适配**。
4
4
 
5
5
  ---
6
6
 
7
7
  ## 🌟 核心特性 (Key Features)
8
8
 
9
9
  - ⚡ **Vue 3 + `<script setup>` 驱动**:全量采用 Vue 3 Composition API 重构,逻辑清晰,性能卓越;
10
+ - 📘 **TypeScript 原生类型支持**:内置 `index.d.ts` 声明文件与 `@vue/runtime-core` 全局组件模板智能补全,提供极其流畅的 IDE 编码体验;
10
11
  - 🎨 **极奢流光美学设计**:拒绝大众平庸调色,采用现代微渐变、毛玻璃浮岛、Bento 悬浮卡片与动效细节;
11
12
  - 📱 **100% 微信小程序 + H5 + App 全端兼容**:重构虚拟节点 `virtualHost: true`,彻底消除小程序自定义组件壳导致的 Flex 错位与样式压缩问题;
12
13
  - 🌙 **原生暗黑模式 (Dark Mode)**:全量组件支持 `prefers-color-scheme: dark` 自动跟从系统深色切换;
13
14
  - 📦 **支持 `easycom` 按需加载**:无需手动 `import` 组件,随用随写,打包体积小巧;
14
- - 🛠️ **完整工具链集结**:自带网络请求拦截器 (`http`)、表单正则校验 (`validate`)、脱敏/格式化 (`format`) 与颜色计算器 (`color`)。
15
+ - 🛠️ **完整工具链集结 (`$mu`)**:自带网络请求拦截器 (`http`)、表单正则校验 (`validate`)、脱敏/格式化 (`format`) 与颜色计算器 (`color`)。
15
16
 
16
17
  ---
17
18
 
@@ -19,12 +20,13 @@
19
20
 
20
21
  ```text
21
22
  uni_modules/muzhiyu-ui/
22
- ├── components/ <-- 89+ 核心 UI 组件
23
+ ├── components/ <-- 90+ 核心 UI 组件
23
24
  ├── utils/ <-- 统一网络请求与工具函数
24
25
  │ ├── request.js <-- HTTP 客户端拦截器
25
26
  │ └── index.js <-- 正则/格式化/脱敏工具箱
26
- ├── index.js <-- Vue3 插件注册入口
27
- ├── uni.scss <-- 全局 SCSS 主题变量
27
+ ├── index.js <-- Vue 3 插件注册入口
28
+ ├── index.d.ts <-- TypeScript 全量类型声明文件
29
+ ├── theme.scss <-- 全局 SCSS 主题变量
28
30
  └── package.json <-- 插件市场配置文件
29
31
  ```
30
32
 
@@ -110,12 +112,13 @@ console.log(uni.$mu.validate.isEmail('test@example.com')) // true
110
112
 
111
113
  ---
112
114
 
113
- ## 📚 89+ 核心组件全景清单
115
+ ## 📚 90+ 核心组件全景清单
114
116
 
115
117
  ### 1. 基础组件 (Basic)
116
118
  | 组件名 | 说明 | 示例标签 |
117
119
  | :--- | :--- | :--- |
118
120
  | **mu-button** | 极奢按钮(支持流光、圆角、加载、禁用与各种尺寸) | `<mu-button type="primary">确认提交</mu-button>` |
121
+ | **mu-image** | 极奢图片(支持骨架屏占位、失败降级、圆角/头像、全屏预览、淡入) | `<mu-image src="..." width="200" height="200" preview />` |
119
122
  | **mu-icon** | 矢量图标(内置 100+ 高频极简图标库) | `<mu-icon name="heart" size="24" color="#F43F5E" />` |
120
123
  | **mu-cell** | 单元格组(支持图标、箭头、副标题与右侧插槽) | `<mu-cell title="个人资料" is-link />` |
121
124
  | **mu-tag** | 标签(支持渐变、镂空、胶囊与点状) | `<mu-tag type="success">已完成</mu-tag>` |
@@ -199,4 +202,4 @@ const gridList = [
199
202
 
200
203
  ## 📄 开源协议 (License)
201
204
 
202
- [MIT License](LICENSE) - 欢迎自由使用于商业与开源项目!
205
+ [MIT License](https://opensource.org/licenses/MIT)
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <view
3
3
  class="mu-config-provider"
4
- :class="[computedTheme === 'dark' && 'mu-dark']"
4
+ :class="[computedTheme === 'dark' ? 'mu-dark' : 'mu-light']"
5
5
  :style="providerStyle"
6
6
  >
7
7
  <slot></slot>
@@ -14,26 +14,53 @@ import { computed, provide } from 'vue'
14
14
  import MuToast from '../mu-toast/mu-toast.vue'
15
15
 
16
16
  const props = defineProps({
17
- theme: { type: String, default: 'light' }, // light | dark
18
- primaryColor: { type: String, default: '#171717' },
17
+ theme: { type: String, default: 'light' }, // light | dark | auto
18
+ primaryColor: { type: String, default: '' },
19
+ successColor: { type: String, default: '' },
20
+ warningColor: { type: String, default: '' },
21
+ errorColor: { type: String, default: '' },
22
+ borderRadius: { type: String, default: '' },
19
23
  zIndex: { type: Number, default: 1000 },
20
24
  unit: { type: String, default: 'rpx' }
21
25
  })
22
26
 
23
27
  const computedTheme = computed(() => props.theme)
24
28
  const computedPrimary = computed(() => props.primaryColor)
29
+ const computedSuccess = computed(() => props.successColor)
30
+ const computedWarning = computed(() => props.warningColor)
31
+ const computedError = computed(() => props.errorColor)
32
+ const computedRadius = computed(() => props.borderRadius)
33
+ const computedZIndex = computed(() => props.zIndex)
34
+ const computedUnit = computed(() => props.unit)
25
35
 
26
36
  provide('muConfig', {
27
37
  theme: computedTheme,
28
38
  primaryColor: computedPrimary,
29
- zIndex: computed(() => props.zIndex),
30
- unit: computed(() => props.unit)
39
+ successColor: computedSuccess,
40
+ warningColor: computedWarning,
41
+ errorColor: computedError,
42
+ borderRadius: computedRadius,
43
+ zIndex: computedZIndex,
44
+ unit: computedUnit
31
45
  })
32
46
 
33
47
  const providerStyle = computed(() => {
34
48
  const style = {}
35
49
  if (props.primaryColor) {
36
50
  style['--mu-primary'] = props.primaryColor
51
+ style['--mu-primary-gradient'] = props.primaryColor
52
+ }
53
+ if (props.successColor) {
54
+ style['--mu-success'] = props.successColor
55
+ }
56
+ if (props.warningColor) {
57
+ style['--mu-warning'] = props.warningColor
58
+ }
59
+ if (props.errorColor) {
60
+ style['--mu-error'] = props.errorColor
61
+ }
62
+ if (props.borderRadius) {
63
+ style['--mu-radius-base'] = props.borderRadius
37
64
  }
38
65
  return style
39
66
  })
@@ -49,6 +76,14 @@ const providerStyle = computed(() => {
49
76
  &.mu-dark {
50
77
  background-color: #08080C;
51
78
  color: #E2E8F0;
79
+ --mu-bg-page: #08080C;
80
+ --mu-text-primary: #FFFFFF;
81
+ --mu-text-secondary: #94A3B8;
82
+ --mu-border-color: rgba(255, 255, 255, 0.12);
83
+ }
84
+ &.mu-light {
85
+ background-color: #F8FAFC;
86
+ color: #0F172A;
52
87
  }
53
88
  }
54
89
  </style>
@@ -0,0 +1,265 @@
1
+ <template>
2
+ <view
3
+ class="mu-image"
4
+ :class="[
5
+ round && 'mu-image--round',
6
+ loading && 'mu-image--loading',
7
+ isError && 'mu-image--error'
8
+ ]"
9
+ :style="wrapStyle"
10
+ @tap="handleClick"
11
+ @click="handleClick"
12
+ >
13
+ <!-- 主图片内容 -->
14
+ <image
15
+ v-if="!isError"
16
+ class="mu-image__inner"
17
+ :class="[fade && loaded && 'mu-image__inner--fade']"
18
+ :src="src"
19
+ :mode="mode"
20
+ :lazy-load="lazyLoad"
21
+ :show-menu-by-longpress="showMenuByLongpress"
22
+ :style="imageStyle"
23
+ @load="handleLoad"
24
+ @error="handleError"
25
+ />
26
+
27
+ <!-- 加载状态/骨架屏占位 -->
28
+ <view
29
+ v-if="loading && showLoading"
30
+ class="mu-image__placeholder mu-image__placeholder--loading"
31
+ :style="placeholderStyle"
32
+ >
33
+ <slot name="loading">
34
+ <view v-if="loadingIcon === 'loading'" class="mu-image__spinner"></view>
35
+ <mu-icon v-else :name="loadingIcon" size="36" color="#94A3B8" />
36
+ </slot>
37
+ </view>
38
+
39
+ <!-- 加载失败占位 -->
40
+ <view
41
+ v-if="isError && showError"
42
+ class="mu-image__placeholder mu-image__placeholder--error"
43
+ :style="placeholderStyle"
44
+ >
45
+ <slot name="error">
46
+ <view class="mu-image__error-box">
47
+ <mu-icon :name="errorIcon" size="44" color="#CBD5E1" />
48
+ <text v-if="errorText" class="mu-image__error-text">{{ errorText }}</text>
49
+ </view>
50
+ </slot>
51
+ </view>
52
+ </view>
53
+ </template>
54
+
55
+ <script setup>
56
+ import { ref, computed, watch } from 'vue'
57
+
58
+ defineOptions({
59
+ name: 'MuImage',
60
+ options: {
61
+ virtualHost: true,
62
+ styleIsolation: 'shared'
63
+ }
64
+ })
65
+
66
+ const props = defineProps({
67
+ src: { type: String, default: '' },
68
+ mode: { type: String, default: 'aspectFill' },
69
+ width: { type: [Number, String], default: '100%' },
70
+ height: { type: [Number, String], default: '100%' },
71
+ radius: { type: [Number, String], default: 0 },
72
+ round: { type: Boolean, default: false },
73
+ lazyLoad: { type: Boolean, default: true },
74
+ showLoading: { type: Boolean, default: true },
75
+ showError: { type: Boolean, default: true },
76
+ loadingIcon: { type: String, default: 'loading' },
77
+ errorIcon: { type: String, default: 'image' },
78
+ errorText: { type: String, default: '' },
79
+ preview: { type: Boolean, default: false },
80
+ fade: { type: Boolean, default: true },
81
+ duration: { type: [Number, String], default: 300 },
82
+ bgColor: { type: String, default: '' },
83
+ showMenuByLongpress: { type: Boolean, default: false }
84
+ })
85
+
86
+ const emit = defineEmits(['click', 'load', 'error'])
87
+
88
+ const loading = ref(true)
89
+ const isError = ref(false)
90
+ const loaded = ref(false)
91
+
92
+ watch(
93
+ () => props.src,
94
+ (val) => {
95
+ if (val) {
96
+ loading.value = true
97
+ isError.value = false
98
+ loaded.value = false
99
+ } else {
100
+ loading.value = false
101
+ isError.value = true
102
+ }
103
+ },
104
+ { immediate: true }
105
+ )
106
+
107
+ const formatUnit = (val) => {
108
+ if (typeof val === 'number') return `${val}rpx`
109
+ if (!val) return 'auto'
110
+ return /^\d+$/.test(val) ? `${val}rpx` : val
111
+ }
112
+
113
+ const wrapStyle = computed(() => {
114
+ const style = {
115
+ width: formatUnit(props.width)
116
+ }
117
+
118
+ // 宽度适应模式下,高度自动按比例自适应
119
+ if (props.mode === 'widthFix') {
120
+ style.height = 'auto'
121
+ } else if (props.mode === 'heightFix') {
122
+ style.width = 'auto'
123
+ style.height = formatUnit(props.height)
124
+ } else {
125
+ style.height = formatUnit(props.height)
126
+ }
127
+
128
+ if (props.round) {
129
+ style.borderRadius = '50%'
130
+ } else if (props.radius) {
131
+ style.borderRadius = formatUnit(props.radius)
132
+ }
133
+ return style
134
+ })
135
+
136
+ const placeholderStyle = computed(() => {
137
+ const style = {}
138
+ if (props.bgColor) {
139
+ style.backgroundColor = props.bgColor
140
+ }
141
+ return style
142
+ })
143
+
144
+ const imageStyle = computed(() => {
145
+ const style = {}
146
+ if (props.fade && !loaded.value) {
147
+ style.opacity = 0
148
+ } else {
149
+ style.opacity = 1
150
+ }
151
+ style.transition = `opacity ${props.duration}ms ease`
152
+ return style
153
+ })
154
+
155
+ function handleLoad(e) {
156
+ loading.value = false
157
+ isError.value = false
158
+ loaded.value = true
159
+ emit('load', e)
160
+ }
161
+
162
+ function handleError(e) {
163
+ loading.value = false
164
+ isError.value = true
165
+ loaded.value = false
166
+ emit('error', e)
167
+ }
168
+
169
+ function handleClick(e) {
170
+ emit('click', e)
171
+ if (props.preview && props.src && !isError.value) {
172
+ uni.previewImage({
173
+ urls: [props.src],
174
+ current: props.src
175
+ })
176
+ }
177
+ }
178
+ </script>
179
+
180
+ <style lang="scss">
181
+ .mu-image {
182
+ position: relative;
183
+ display: inline-block;
184
+ overflow: hidden;
185
+ box-sizing: border-box;
186
+ vertical-align: middle;
187
+
188
+ &--round {
189
+ border-radius: 50% !important;
190
+ }
191
+
192
+ &__inner {
193
+ width: 100%;
194
+ height: 100%;
195
+ display: block;
196
+ will-change: opacity;
197
+ }
198
+
199
+ &__placeholder {
200
+ position: absolute;
201
+ top: 0;
202
+ left: 0;
203
+ right: 0;
204
+ bottom: 0;
205
+ display: flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+ z-index: 1;
209
+ background-color: var(--mu-bg-gray, rgba(241, 245, 249, 0.7));
210
+ transition: background-color 0.3s ease;
211
+ }
212
+
213
+ &__spinner {
214
+ width: 36rpx;
215
+ height: 36rpx;
216
+ border: 4rpx solid rgba(148, 163, 184, 0.2);
217
+ border-top-color: #94A3B8;
218
+ border-radius: 50%;
219
+ animation: mu-image-spin 0.8s linear infinite;
220
+ }
221
+
222
+ &__error-box {
223
+ display: flex;
224
+ flex-direction: column;
225
+ align-items: center;
226
+ justify-content: center;
227
+ }
228
+
229
+ &__error-text {
230
+ font-size: 22rpx;
231
+ color: #94A3B8;
232
+ margin-top: 8rpx;
233
+ }
234
+ }
235
+
236
+ @keyframes mu-image-spin {
237
+ 0% {
238
+ transform: rotate(0deg);
239
+ }
240
+ 100% {
241
+ transform: rotate(360deg);
242
+ }
243
+ }
244
+
245
+ /* 暗黑模式自适应跟从 */
246
+ .mu-dark {
247
+ .mu-image__placeholder {
248
+ background-color: rgba(30, 30, 44, 0.8) !important;
249
+ }
250
+ .mu-image__spinner {
251
+ border-color: rgba(255, 255, 255, 0.15);
252
+ border-top-color: #FFFFFF;
253
+ }
254
+ }
255
+
256
+ @media (prefers-color-scheme: dark) {
257
+ .mu-image__placeholder {
258
+ background-color: rgba(30, 30, 44, 0.8);
259
+ }
260
+ .mu-image__spinner {
261
+ border-color: rgba(255, 255, 255, 0.15);
262
+ border-top-color: #FFFFFF;
263
+ }
264
+ }
265
+ </style>
package/index.d.ts ADDED
@@ -0,0 +1,220 @@
1
+ /**
2
+ * MuzhiyuUI 极奢全端组件库统一 TypeScript 类型定义
3
+ * @author muzhiyu
4
+ * @version 1.0.0
5
+ */
6
+
7
+ import { App } from 'vue'
8
+
9
+ export interface MuHttpConfig {
10
+ baseUrl?: string
11
+ header?: Record<string, string>
12
+ timeout?: number
13
+ dataType?: string
14
+ responseType?: string
15
+ sslVerify?: boolean
16
+ withCredentials?: boolean
17
+ }
18
+
19
+ export interface MuHttp {
20
+ get<T = any>(url: string, data?: object, config?: MuHttpConfig): Promise<T>
21
+ post<T = any>(url: string, data?: object, config?: MuHttpConfig): Promise<T>
22
+ put<T = any>(url: string, data?: object, config?: MuHttpConfig): Promise<T>
23
+ delete<T = any>(url: string, data?: object, config?: MuHttpConfig): Promise<T>
24
+ upload<T = any>(url: string, config?: MuHttpConfig): Promise<T>
25
+ download<T = any>(url: string, config?: MuHttpConfig): Promise<T>
26
+ request<T = any>(config: MuHttpConfig & { url: string; method?: string; data?: object }): Promise<T>
27
+ interceptor: {
28
+ request: (callback: (config: MuHttpConfig) => MuHttpConfig | Promise<MuHttpConfig>) => void
29
+ response: (callback: (response: any) => any | Promise<any>, errorCallback?: (error: any) => any) => void
30
+ }
31
+ }
32
+
33
+ export interface MuUtil {
34
+ trim(value?: string): string
35
+ replaceAll(text?: string, search?: string, replacement?: string): string
36
+ maskPhone(num?: string | number): string
37
+ formatMoney(money?: number | string): string
38
+ formatDate(format?: string, date?: Date | string | number): string
39
+ debounce<T extends (...args: any[]) => any>(fn: T, delay?: number): T
40
+ throttle<T extends (...args: any[]) => any>(fn: T, interval?: number): T
41
+ deepClone<T>(target: T): T
42
+ guid(length?: number, firstU?: boolean, radix?: number): string
43
+ }
44
+
45
+ export interface MuValidate {
46
+ isEmail(val: string): boolean
47
+ isMobile(val: string): boolean
48
+ isIdCard(val: string): boolean
49
+ isUrl(val: string): boolean
50
+ isCarNo(val: string): boolean
51
+ isChinese(val: string): boolean
52
+ isNumber(val: string): boolean
53
+ isEmpty(val: any): boolean
54
+ }
55
+
56
+ export interface MuFormat {
57
+ money(amount: number | string): string
58
+ date(format?: string, date?: Date | string | number): string
59
+ phone(num: string | number): string
60
+ }
61
+
62
+ export interface MuColor {
63
+ hexToRgb(hex: string): string
64
+ rgbToHex(r: number, g: number, b: number): string
65
+ lighten(color: string, amount: number): string
66
+ darken(color: string, amount: number): string
67
+ }
68
+
69
+ export interface MuToastOptions {
70
+ title?: string
71
+ type?: 'success' | 'error' | 'fail' | 'loading' | 'default'
72
+ duration?: number
73
+ icon?: string
74
+ position?: 'top' | 'center' | 'bottom'
75
+ }
76
+
77
+ export interface MuNotifyOptions {
78
+ message: string
79
+ type?: 'primary' | 'success' | 'warning' | 'error' | 'info'
80
+ duration?: number
81
+ safeAreaInsetTop?: boolean
82
+ }
83
+
84
+ export interface MuLoadingPageOptions {
85
+ text?: string
86
+ type?: 'logo' | 'spinner' | 'pulse'
87
+ bg?: string
88
+ color?: string
89
+ }
90
+
91
+ export interface MuInstance {
92
+ http: MuHttp
93
+ util: MuUtil
94
+ validate: MuValidate
95
+ format: MuFormat
96
+ color: MuColor
97
+ toast(title: string | MuToastOptions, type?: string, options?: object): void
98
+ notify(options: string | MuNotifyOptions): void
99
+ loadingPage(text?: string | MuLoadingPageOptions, type?: string, options?: object): void
100
+ }
101
+
102
+ declare const mu: MuInstance & {
103
+ install(app: App): void
104
+ }
105
+
106
+ export const http: MuHttp
107
+ export const util: MuUtil
108
+ export const validate: MuValidate
109
+ export const format: MuFormat
110
+ export const color: MuColor
111
+ export const toast: (title: string | MuToastOptions, type?: string, options?: object) => void
112
+ export const notify: (options: string | MuNotifyOptions) => void
113
+ export const loadingPage: (text?: string | MuLoadingPageOptions, type?: string, options?: object) => void
114
+
115
+ export default mu
116
+
117
+ declare global {
118
+ interface Uni {
119
+ $mu: MuInstance
120
+ $toast: (title: string | MuToastOptions, type?: string, options?: object) => void
121
+ }
122
+ }
123
+
124
+ declare module '@vue/runtime-core' {
125
+ export interface ComponentCustomProperties {
126
+ $mu: MuInstance
127
+ }
128
+
129
+ export interface GlobalComponents {
130
+ MuActionSheet: typeof import('./components/muzhiyu/mu-action-sheet/mu-action-sheet.vue')['default']
131
+ MuAlert: typeof import('./components/muzhiyu/mu-alert/mu-alert.vue')['default']
132
+ MuBackTop: typeof import('./components/muzhiyu/mu-back-top/mu-back-top.vue')['default']
133
+ MuBadge: typeof import('./components/muzhiyu/mu-badge/mu-badge.vue')['default']
134
+ MuBarcode: typeof import('./components/muzhiyu/mu-barcode/mu-barcode.vue')['default']
135
+ MuBlank: typeof import('./components/muzhiyu/mu-blank/mu-blank.vue')['default']
136
+ MuBottomNav: typeof import('./components/muzhiyu/mu-bottom-nav/mu-bottom-nav.vue')['default']
137
+ MuBubble: typeof import('./components/muzhiyu/mu-bubble/mu-bubble.vue')['default']
138
+ MuButton: typeof import('./components/muzhiyu/mu-button/mu-button.vue')['default']
139
+ MuCalendar: typeof import('./components/muzhiyu/mu-calendar/mu-calendar.vue')['default']
140
+ MuCarInput: typeof import('./components/muzhiyu/mu-car-input/mu-car-input.vue')['default']
141
+ MuCard: typeof import('./components/muzhiyu/mu-card/mu-card.vue')['default']
142
+ MuCascader: typeof import('./components/muzhiyu/mu-cascader/mu-cascader.vue')['default']
143
+ MuCell: typeof import('./components/muzhiyu/mu-cell/mu-cell.vue')['default']
144
+ MuCheckbox: typeof import('./components/muzhiyu/mu-checkbox/mu-checkbox.vue')['default']
145
+ MuCheckboxGroup: typeof import('./components/muzhiyu/mu-checkbox-group/mu-checkbox-group.vue')['default']
146
+ MuCodeInput: typeof import('./components/muzhiyu/mu-code-input/mu-code-input.vue')['default']
147
+ MuCollapse: typeof import('./components/muzhiyu/mu-collapse/mu-collapse.vue')['default']
148
+ MuColorPicker: typeof import('./components/muzhiyu/mu-color-picker/mu-color-picker.vue')['default']
149
+ MuConfig: typeof import('./components/muzhiyu/mu-config/mu-config.vue')['default']
150
+ MuCountdown: typeof import('./components/muzhiyu/mu-countdown/mu-countdown.vue')['default']
151
+ MuCropper: typeof import('./components/muzhiyu/mu-cropper/mu-cropper.vue')['default']
152
+ MuDatePicker: typeof import('./components/muzhiyu/mu-date-picker/mu-date-picker.vue')['default']
153
+ MuDatetime: typeof import('./components/muzhiyu/mu-datetime/mu-datetime.vue')['default']
154
+ MuDivider: typeof import('./components/muzhiyu/mu-divider/mu-divider.vue')['default']
155
+ MuDrawer: typeof import('./components/muzhiyu/mu-drawer/mu-drawer.vue')['default']
156
+ MuDropdown: typeof import('./components/muzhiyu/mu-dropdown/mu-dropdown.vue')['default']
157
+ MuEmpty: typeof import('./components/muzhiyu/mu-empty/mu-empty.vue')['default']
158
+ MuFab: typeof import('./components/muzhiyu/mu-fab/mu-fab.vue')['default']
159
+ MuFooter: typeof import('./components/muzhiyu/mu-footer/mu-footer.vue')['default']
160
+ MuForm: typeof import('./components/muzhiyu/mu-form/mu-form.vue')['default']
161
+ MuGrid: typeof import('./components/muzhiyu/mu-grid/mu-grid.vue')['default']
162
+ MuGridItem: typeof import('./components/muzhiyu/mu-grid-item/mu-grid-item.vue')['default']
163
+ MuHtml: typeof import('./components/muzhiyu/mu-html/mu-html.vue')['default']
164
+ MuIcon: typeof import('./components/muzhiyu/mu-icon/mu-icon.vue')['default']
165
+ MuImage: typeof import('./components/muzhiyu/mu-image/mu-image.vue')['default']
166
+ MuImageGrid: typeof import('./components/muzhiyu/mu-image-grid/mu-image-grid.vue')['default']
167
+ MuImagePreview: typeof import('./components/muzhiyu/mu-image-preview/mu-image-preview.vue')['default']
168
+ MuIndexList: typeof import('./components/muzhiyu/mu-index-list/mu-index-list.vue')['default']
169
+ MuInput: typeof import('./components/muzhiyu/mu-input/mu-input.vue')['default']
170
+ MuInputNumber: typeof import('./components/muzhiyu/mu-input-number/mu-input-number.vue')['default']
171
+ MuKeyboard: typeof import('./components/muzhiyu/mu-keyboard/mu-keyboard.vue')['default']
172
+ MuList: typeof import('./components/muzhiyu/mu-list/mu-list.vue')['default']
173
+ MuLoading: typeof import('./components/muzhiyu/mu-loading/mu-loading.vue')['default']
174
+ MuLoadingPage: typeof import('./components/muzhiyu/mu-loading-page/mu-loading-page.vue')['default']
175
+ MuLoadmore: typeof import('./components/muzhiyu/mu-loadmore/mu-loadmore.vue')['default']
176
+ MuModal: typeof import('./components/muzhiyu/mu-modal/mu-modal.vue')['default']
177
+ MuNavbar: typeof import('./components/muzhiyu/mu-navbar/mu-navbar.vue')['default']
178
+ MuNomore: typeof import('./components/muzhiyu/mu-nomore/mu-nomore.vue')['default']
179
+ MuNoticeBar: typeof import('./components/muzhiyu/mu-notice-bar/mu-notice-bar.vue')['default']
180
+ MuNotify: typeof import('./components/muzhiyu/mu-notify/mu-notify.vue')['default']
181
+ MuOverlay: typeof import('./components/muzhiyu/mu-overlay/mu-overlay.vue')['default']
182
+ MuPagination: typeof import('./components/muzhiyu/mu-pagination/mu-pagination.vue')['default']
183
+ MuPasswordInput: typeof import('./components/muzhiyu/mu-password-input/mu-password-input.vue')['default']
184
+ MuPicker: typeof import('./components/muzhiyu/mu-picker/mu-picker.vue')['default']
185
+ MuPopup: typeof import('./components/muzhiyu/mu-popup/mu-popup.vue')['default']
186
+ MuProgress: typeof import('./components/muzhiyu/mu-progress/mu-progress.vue')['default']
187
+ MuPullRefresh: typeof import('./components/muzhiyu/mu-pull-refresh/mu-pull-refresh.vue')['default']
188
+ MuQrcode: typeof import('./components/muzhiyu/mu-qrcode/mu-qrcode.vue')['default']
189
+ MuRadio: typeof import('./components/muzhiyu/mu-radio/mu-radio.vue')['default']
190
+ MuRadioGroup: typeof import('./components/muzhiyu/mu-radio-group/mu-radio-group.vue')['default']
191
+ MuRate: typeof import('./components/muzhiyu/mu-rate/mu-rate.vue')['default']
192
+ MuSearch: typeof import('./components/muzhiyu/mu-search/mu-search.vue')['default']
193
+ MuSection: typeof import('./components/muzhiyu/mu-section/mu-section.vue')['default']
194
+ MuSelect: typeof import('./components/muzhiyu/mu-select/mu-select.vue')['default']
195
+ MuShareSheet: typeof import('./components/muzhiyu/mu-share-sheet/mu-share-sheet.vue')['default']
196
+ MuSidebar: typeof import('./components/muzhiyu/mu-sidebar/mu-sidebar.vue')['default']
197
+ MuSignature: typeof import('./components/muzhiyu/mu-signature/mu-signature.vue')['default']
198
+ MuSkeleton: typeof import('./components/muzhiyu/mu-skeleton/mu-skeleton.vue')['default']
199
+ MuSlider: typeof import('./components/muzhiyu/mu-slider/mu-slider.vue')['default']
200
+ MuSpace: typeof import('./components/muzhiyu/mu-space/mu-space.vue')['default']
201
+ MuSteps: typeof import('./components/muzhiyu/mu-steps/mu-steps.vue')['default']
202
+ MuSticky: typeof import('./components/muzhiyu/mu-sticky/mu-sticky.vue')['default']
203
+ MuSwipeCell: typeof import('./components/muzhiyu/mu-swipe-cell/mu-swipe-cell.vue')['default']
204
+ MuSwiper: typeof import('./components/muzhiyu/mu-swiper/mu-swiper.vue')['default']
205
+ MuSwitch: typeof import('./components/muzhiyu/mu-switch/mu-switch.vue')['default']
206
+ MuTabbar: typeof import('./components/muzhiyu/mu-tabbar/mu-tabbar.vue')['default']
207
+ MuTable: typeof import('./components/muzhiyu/mu-table/mu-table.vue')['default']
208
+ MuTabs: typeof import('./components/muzhiyu/mu-tabs/mu-tabs.vue')['default']
209
+ MuTag: typeof import('./components/muzhiyu/mu-tag/mu-tag.vue')['default']
210
+ MuTextEllipsis: typeof import('./components/muzhiyu/mu-text-ellipsis/mu-text-ellipsis.vue')['default']
211
+ MuTimeline: typeof import('./components/muzhiyu/mu-timeline/mu-timeline.vue')['default']
212
+ MuTips: typeof import('./components/muzhiyu/mu-tips/mu-tips.vue')['default']
213
+ MuToast: typeof import('./components/muzhiyu/mu-toast/mu-toast.vue')['default']
214
+ MuTransfer: typeof import('./components/muzhiyu/mu-transfer/mu-transfer.vue')['default']
215
+ MuTree: typeof import('./components/muzhiyu/mu-tree/mu-tree.vue')['default']
216
+ MuUpload: typeof import('./components/muzhiyu/mu-upload/mu-upload.vue')['default']
217
+ MuWaterfall: typeof import('./components/muzhiyu/mu-waterfall/mu-waterfall.vue')['default']
218
+ MuWatermark: typeof import('./components/muzhiyu/mu-watermark/mu-watermark.vue')['default']
219
+ }
220
+ }
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "muzhiyu-ui",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "基于 UniApp Vue3 + SCSS 打造的全端极奢组件库",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
6
7
  "scripts": {
7
8
  "docs:dev": "npx vitepress dev docs",
8
9
  "docs:build": "npx vitepress build docs",
@@ -12,7 +13,8 @@
12
13
  "components",
13
14
  "utils",
14
15
  "theme.scss",
15
- "index.js"
16
+ "index.js",
17
+ "index.d.ts"
16
18
  ],
17
19
  "keywords": [
18
20
  "uniapp",
@@ -27,7 +29,7 @@
27
29
  "uni_modules": {
28
30
  "id": "muzhiyu-ui",
29
31
  "name": "muzhiyu-ui 极奢组件库",
30
- "version": "1.0.0",
32
+ "version": "1.0.2",
31
33
  "description": "基于 UniApp Vue3 + SCSS 打造的全端极奢 UI 组件库",
32
34
  "site": "",
33
35
  "displayName": "MuzhiyuUI 极奢全端组件库"
package/theme.scss ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * MuZhiYuUI Panda Monochrome Design Tokens & Dark Mode System
3
+ * 极奢黑白熊猫风 — 极简深邃黑白、纤细线条微边框、黑白双轨制高对比度
4
+ */
5
+
6
+ /* ===== 亮色模式核心主题色 (Light Mode Panda Black Tokens) ===== */
7
+ $mu-primary: #171717; // 亮色熊猫主色 (深邃极致黑)
8
+ $mu-primary-hover: #333333;
9
+ $mu-primary-active: #000000;
10
+ $mu-primary-bg: rgba(23, 23, 23, 0.08);
11
+ $mu-primary-border: rgba(23, 23, 23, 0.25);
12
+ $mu-primary-gradient: #171717;
13
+ $mu-sky-gradient: #171717;
14
+
15
+ /* ===== 暗黑模式自适应高亮主题色 (Dark Mode Panda White Tokens - 纯白高对比) ===== */
16
+ $mu-dark-primary: #FFFFFF; // 暗黑熊猫主色 (纯白反色,在纯黑背景上极致清晰)
17
+ $mu-dark-primary-hover: #F1F5F9;
18
+ $mu-dark-primary-bg: rgba(255, 255, 255, 0.15);
19
+ $mu-dark-primary-border: rgba(255, 255, 255, 0.35);
20
+ $mu-dark-primary-gradient: #FFFFFF;
21
+
22
+ /* ===== 语义色 ===== */
23
+ $mu-success: #10B981;
24
+ $mu-success-bg: rgba(16, 185, 129, 0.08);
25
+ $mu-success-border: rgba(16, 185, 129, 0.25);
26
+ $mu-success-gradient: #10B981;
27
+
28
+ $mu-warning: #F59E0B;
29
+ $mu-warning-bg: rgba(245, 158, 11, 0.08);
30
+ $mu-warning-border: rgba(245, 158, 11, 0.25);
31
+ $mu-warning-gradient: #F59E0B;
32
+
33
+ $mu-error: #F43F5E;
34
+ $mu-error-bg: rgba(244, 63, 94, 0.08);
35
+ $mu-error-border: rgba(244, 63, 94, 0.25);
36
+ $mu-error-gradient: #F43F5E;
37
+
38
+ $mu-info: #38BDF8;
39
+ $mu-info-bg: rgba(56, 189, 248, 0.08);
40
+ $mu-info-border: rgba(56, 189, 248, 0.25);
41
+
42
+ /* 别名映射与向下兼容 */
43
+ $mu-gradient-primary: $mu-primary-gradient;
44
+ $mu-gradient-success: $mu-success-gradient;
45
+ $mu-gradient-warning: $mu-warning-gradient;
46
+ $mu-gradient-danger: $mu-error-gradient;
47
+ $mu-gradient-error: $mu-error-gradient;
48
+ $mu-danger: $mu-error;
49
+ $mu-danger-bg: $mu-error-bg;
50
+ $mu-danger-border: $mu-error-border;
51
+
52
+ /* ===== Slate 中性色阶 ===== */
53
+ $mu-text-primary: #0F172A; // 主标题
54
+ $mu-text-secondary: #475569; // 次要文本
55
+ $mu-text-tertiary: #94A3B8; // 辅助说明
56
+ $mu-text-disabled: #CBD5E1; // 禁用文本
57
+ $mu-text-placeholder: #94A3B8; // 占位
58
+ $mu-text-inverse: #FFFFFF; // 反色文本
59
+
60
+ /* ===== 扁平液态玻璃背景与发光外壳 ===== */
61
+ $mu-bg-base: rgba(255, 255, 255, 0.85);
62
+ $mu-bg-page: #F8FAFC;
63
+ $mu-bg-gray: #F1F5F9;
64
+ $mu-bg-hover: rgba(255, 255, 255, 0.95);
65
+ $mu-bg-active: rgba(241, 245, 249, 0.9);
66
+ $mu-bg-mask: rgba(15, 23, 42, 0.6);
67
+ $mu-glass-bg: rgba(255, 255, 255, 0.72);
68
+ $mu-glass-border: rgba(255, 255, 255, 0.9);
69
+
70
+ /* ===== 纤细微边框与高光 ===== */
71
+ $mu-border: rgba(226, 232, 240, 0.8);
72
+ $mu-border-color: rgba(226, 232, 240, 0.8);
73
+ $mu-border-light: rgba(241, 245, 249, 0.8);
74
+ $mu-border-dark: #CBD5E1;
75
+ $mu-border-highlight: rgba(255, 255, 255, 0.95);
76
+
77
+ /* ===== 透明度 ===== */
78
+ $mu-opacity-disabled: 0.45;
79
+
80
+ /* ===== 字号 ===== */
81
+ $mu-font-xs: 20rpx;
82
+ $mu-font-sm: 24rpx;
83
+ $mu-font-base: 28rpx;
84
+ $mu-font-md: 30rpx;
85
+ $mu-font-lg: 32rpx;
86
+ $mu-font-xl: 36rpx;
87
+ $mu-font-2xl: 44rpx;
88
+ $mu-font-3xl: 56rpx;
89
+
90
+ $mu-line-height: 1.5;
91
+
92
+ /* ===== 空间网格 ===== */
93
+ $mu-space-1: 8rpx;
94
+ $mu-space-2: 16rpx;
95
+ $mu-space-3: 24rpx;
96
+ $mu-space-4: 32rpx;
97
+ $mu-space-5: 40rpx;
98
+ $mu-space-6: 48rpx;
99
+ $mu-space-8: 64rpx;
100
+ $mu-space-10: 80rpx;
101
+ $mu-space-12: 96rpx;
102
+
103
+ /* ===== 移动端精工 Squircle 微圆角矩阵 (Mobile Native Squircle Tokens) ===== */
104
+ $mu-radius-xs: 6rpx; // 3px - 极小微角标/微标签
105
+ $mu-radius-sm: 10rpx; // 5px - 小号按钮/微型输入框
106
+ $mu-radius-md: 16rpx; // 8px - 移动端标准按钮/表单控件 (iOS/Android Native 触控标准)
107
+ $mu-radius-lg: 20rpx; // 10px - 大号按键/提示框
108
+ $mu-radius-xl: 24rpx; // 12px - 移动端卡片/面板容器 (紧凑利落)
109
+ $mu-radius-2xl: 32rpx; // 16px - 模态框/底部抽屉
110
+ $mu-radius-full: 999rpx; // 胶囊圆角 (当 round 属性启用时)
111
+
112
+ /* ===== 扁平弥散阴影 ===== */
113
+ $mu-shadow-sm: 0 4rpx 14rpx rgba(15, 23, 42, 0.03);
114
+ $mu-shadow-md: 0 12rpx 32rpx -4rpx rgba(15, 23, 42, 0.06);
115
+ $mu-shadow-lg: 0 20rpx 48rpx -6rpx rgba(15, 23, 42, 0.1);
116
+ $mu-shadow-glow: 0 12rpx 32rpx -4rpx rgba(23, 23, 23, 0.25);
117
+ $mu-shadow-button-primary: 0 10rpx 28rpx -4rpx rgba(23, 23, 23, 0.35);
118
+
119
+ /* ===== 动效贝塞尔曲线 ===== */
120
+ $mu-ease: cubic-bezier(0.32, 0.72, 0, 1);
121
+ $mu-ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
122
+ $mu-duration-fast: 0.15s;
123
+ $mu-duration: 0.25s;
124
+ $mu-duration-slow: 0.4s;
125
+
126
+ /* ===== Z-Index ===== */
127
+ $mu-z-sticky: 99;
128
+ $mu-z-fixed: 100;
129
+ $mu-z-popup: 999;
130
+ $mu-z-modal: 1000;
131
+ $mu-z-toast: 1001;
132
+
133
+ /* ===== Dark Mode OLED 暗黑变量 ===== */
134
+ $mu-dark-bg-page: #08080C;
135
+ $mu-dark-bg-base: rgba(22, 22, 32, 0.94);
136
+ $mu-dark-bg-panel: rgba(26, 26, 38, 0.96);
137
+ $mu-dark-bg-hover: rgba(36, 36, 50, 0.95);
138
+ $mu-dark-text-primary: #F8FAFC;
139
+ $mu-dark-text-secondary: #94A3B8;
140
+ $mu-dark-text-tertiary: #64748B;
141
+ $mu-dark-border: rgba(255, 255, 255, 0.12);
142
+ $mu-dark-border-light: rgba(255, 255, 255, 0.06);
143
+ $mu-dark-glass-bg: rgba(22, 22, 32, 0.88);
144
+ $mu-dark-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.65);