im-ui-mobile 0.1.11 → 0.1.13
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/components/im-badge/im-badge.vue +21 -30
- package/components/im-stepper/im-stepper.vue +1 -1
- package/components/im-tabs/im-tabs.vue +3 -2
- package/components/im-tabs/utils/compatibility.ts +69 -0
- package/components/im-virtual-list/im-virtual-list.vue +3 -3
- package/package.json +59 -57
- package/styles/functions.scss +24 -0
- package/styles/mixins.scss +148 -0
- package/styles/variables.scss +58 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
!childrenSlot && !isAbsolute ? 'im-badge--standalone' : '',
|
|
9
9
|
isAbsolute ? 'im-badge--absolute' : ''
|
|
10
10
|
]" :style="{
|
|
11
|
-
'--badge-bg-color': bgColor ||
|
|
11
|
+
'--badge-bg-color': bgColor || innerBgColor,
|
|
12
12
|
'--badge-text-color': textColor || undefined,
|
|
13
13
|
'--badge-offset-x': offset[0] + 'px',
|
|
14
14
|
'--badge-offset-y': offset[1] + 'px'
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script setup lang="ts">
|
|
38
|
-
import {
|
|
38
|
+
import { computed, useSlots } from 'vue'
|
|
39
39
|
|
|
40
40
|
// 定义Props
|
|
41
41
|
interface BadgeProps {
|
|
@@ -120,6 +120,20 @@ const typeClass = computed(() => `im-badge--${props.type}`)
|
|
|
120
120
|
const sizeClass = computed(() => `im-badge--${props.size}`)
|
|
121
121
|
const shapeClass = computed(() => `im-badge--${props.shape}`)
|
|
122
122
|
const isAbsolute = computed(() => props.absolute && childrenSlot.value)
|
|
123
|
+
const innerBgColor = computed(() => {
|
|
124
|
+
switch (props.type) {
|
|
125
|
+
case 'primary':
|
|
126
|
+
return '#409eff';
|
|
127
|
+
case 'success':
|
|
128
|
+
return '#67c23a';
|
|
129
|
+
case 'warning':
|
|
130
|
+
return '#e6a23c';
|
|
131
|
+
case 'danger':
|
|
132
|
+
return '#f56c6c';
|
|
133
|
+
case 'info':
|
|
134
|
+
return '#909399';
|
|
135
|
+
}
|
|
136
|
+
})
|
|
123
137
|
|
|
124
138
|
// 事件处理
|
|
125
139
|
const handleClick = (event: MouseEvent) => {
|
|
@@ -133,6 +147,8 @@ defineExpose({
|
|
|
133
147
|
</script>
|
|
134
148
|
|
|
135
149
|
<style lang="scss" scoped>
|
|
150
|
+
@import "../../styles/variables.scss";
|
|
151
|
+
|
|
136
152
|
.im-badge {
|
|
137
153
|
display: inline-flex;
|
|
138
154
|
position: relative;
|
|
@@ -176,36 +192,11 @@ defineExpose({
|
|
|
176
192
|
font-size: 12px;
|
|
177
193
|
font-weight: 500;
|
|
178
194
|
line-height: 1;
|
|
179
|
-
color:
|
|
195
|
+
color: #ffffff;
|
|
180
196
|
text-align: center;
|
|
181
197
|
white-space: nowrap;
|
|
182
198
|
}
|
|
183
199
|
|
|
184
|
-
// 类型样式
|
|
185
|
-
&--primary {
|
|
186
|
-
--badge-bg-color: #409eff;
|
|
187
|
-
--badge-text-color: #ffffff;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
&--success {
|
|
191
|
-
--badge-bg-color: #67c23a;
|
|
192
|
-
--badge-text-color: #ffffff;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
&--warning {
|
|
196
|
-
--badge-bg-color: #e6a23c;
|
|
197
|
-
--badge-text-color: #ffffff;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
&--danger {
|
|
201
|
-
--badge-bg-color: #f56c6c;
|
|
202
|
-
--badge-text-color: #ffffff;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
&--info {
|
|
206
|
-
--badge-bg-color: #909399;
|
|
207
|
-
--badge-text-color: #ffffff;
|
|
208
|
-
}
|
|
209
200
|
|
|
210
201
|
// 尺寸样式
|
|
211
202
|
&--small {
|
|
@@ -302,7 +293,7 @@ defineExpose({
|
|
|
302
293
|
align-items: center;
|
|
303
294
|
justify-content: center;
|
|
304
295
|
background-color: var(--badge-bg-color);
|
|
305
|
-
color: var(--badge-text-color);
|
|
296
|
+
color: var(--badge-text-color) !important;
|
|
306
297
|
|
|
307
298
|
// 添加阴影增强视觉效果
|
|
308
299
|
box-shadow: 0 0 0 1px #fff;
|
|
@@ -316,7 +307,7 @@ defineExpose({
|
|
|
316
307
|
align-items: center;
|
|
317
308
|
justify-content: center;
|
|
318
309
|
background-color: var(--badge-bg-color);
|
|
319
|
-
color: var(--badge-text-color);
|
|
310
|
+
color: var(--badge-text-color) !important;
|
|
320
311
|
|
|
321
312
|
// 添加阴影增强视觉效果
|
|
322
313
|
box-shadow: 0 0 0 1px #fff;
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
</template>
|
|
57
57
|
|
|
58
58
|
<script lang="ts" setup>
|
|
59
|
-
import { ref, computed, watch, nextTick,
|
|
59
|
+
import { ref, computed, watch, nextTick, onMounted } from 'vue'
|
|
60
60
|
import type { StepperProps, StepperEmits } from '../../types/components/stepper'
|
|
61
61
|
import ImIcon from '../im-icon/im-icon.vue'
|
|
62
62
|
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
} from 'vue'
|
|
54
54
|
import type { TabsProps, TabsEmits, TabItem } from '../../types/components/tabs'
|
|
55
55
|
import TabsNavigation from './tabs-navigation.vue'
|
|
56
|
+
import { safeRequestAnimationFrame } from './utils/compatibility'
|
|
56
57
|
|
|
57
58
|
const props = withDefaults(defineProps<TabsProps>(), {
|
|
58
59
|
modelValue: 0,
|
|
@@ -340,7 +341,7 @@ const scrollToActiveTab = () => {
|
|
|
340
341
|
if (!props.scrollable) return
|
|
341
342
|
|
|
342
343
|
// 使用 requestAnimationFrame
|
|
343
|
-
|
|
344
|
+
safeRequestAnimationFrame(() => {
|
|
344
345
|
scrollToActiveTabImpl()
|
|
345
346
|
})
|
|
346
347
|
}
|
|
@@ -436,7 +437,7 @@ const onPageScroll = (event: any) => {
|
|
|
436
437
|
try {
|
|
437
438
|
const scrollTop = event.scrollTop || 0
|
|
438
439
|
|
|
439
|
-
|
|
440
|
+
safeRequestAnimationFrame(() => {
|
|
440
441
|
const query = uni.createSelectorQuery().in(instance)
|
|
441
442
|
|
|
442
443
|
query.select('.im-tabs-sticky').boundingClientRect((res: any) => {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// utils/compatibility.ts
|
|
2
|
+
/**
|
|
3
|
+
* 兼容 requestAnimationFrame
|
|
4
|
+
*/
|
|
5
|
+
export const requestAnimationFrame = (callback: FrameRequestCallback): number => {
|
|
6
|
+
// 微信小程序环境
|
|
7
|
+
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
|
8
|
+
return setTimeout(() => {
|
|
9
|
+
callback(Date.now())
|
|
10
|
+
}, 16) as unknown as number
|
|
11
|
+
// #endif
|
|
12
|
+
|
|
13
|
+
// H5 环境
|
|
14
|
+
// #ifdef H5
|
|
15
|
+
return window.requestAnimationFrame(callback)
|
|
16
|
+
// #endif
|
|
17
|
+
|
|
18
|
+
// App 环境
|
|
19
|
+
// #ifdef APP
|
|
20
|
+
return setTimeout(() => {
|
|
21
|
+
callback(Date.now())
|
|
22
|
+
}, 16) as unknown as number
|
|
23
|
+
// #endif
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 兼容 cancelAnimationFrame
|
|
28
|
+
*/
|
|
29
|
+
export const cancelAnimationFrame = (id: number): void => {
|
|
30
|
+
// 微信小程序环境
|
|
31
|
+
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
|
32
|
+
return clearTimeout(id)
|
|
33
|
+
// #endif
|
|
34
|
+
|
|
35
|
+
// H5 环境
|
|
36
|
+
// #ifdef H5
|
|
37
|
+
return window.cancelAnimationFrame(id)
|
|
38
|
+
// #endif
|
|
39
|
+
|
|
40
|
+
// App 环境
|
|
41
|
+
// #ifdef APP
|
|
42
|
+
return clearTimeout(id)
|
|
43
|
+
// #endif
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 安全执行 requestAnimationFrame,避免错误
|
|
48
|
+
*/
|
|
49
|
+
export const safeRequestAnimationFrame = (callback: FrameRequestCallback): number => {
|
|
50
|
+
try {
|
|
51
|
+
return requestAnimationFrame(callback)
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// 如果 requestAnimationFrame 不存在,使用 setTimeout 模拟
|
|
54
|
+
return setTimeout(() => {
|
|
55
|
+
callback(Date.now())
|
|
56
|
+
}, 16) as unknown as number
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 安全执行 cancelAnimationFrame
|
|
62
|
+
*/
|
|
63
|
+
export const safeCancelAnimationFrame = (id: number): void => {
|
|
64
|
+
try {
|
|
65
|
+
cancelAnimationFrame(id)
|
|
66
|
+
} catch (error) {
|
|
67
|
+
clearTimeout(id)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- 虚拟列表容器 -->
|
|
3
|
-
<scroll-view class="virtual-list" :scroll-y="true" :scroll-with-animation="true" :show-scrollbar="false"
|
|
3
|
+
<scroll-view class="im-virtual-list" :scroll-y="true" :scroll-with-animation="true" :show-scrollbar="false"
|
|
4
4
|
:enhanced="true" :bounces="false" :lower-threshold="lowerThreshold" :upper-threshold="upperThreshold"
|
|
5
5
|
:scroll-top="scrollTop" :scroll-into-view="scrollIntoViewId" @scroll="handleScroll"
|
|
6
6
|
@scrolltolower="handleScrollToLower" @scrolltoupper="handleScrollToUpper">
|
|
@@ -313,7 +313,7 @@ const clearScrollTimer = () => {
|
|
|
313
313
|
const measureContainer = () => {
|
|
314
314
|
nextTick(() => {
|
|
315
315
|
const query = uni.createSelectorQuery().in(getCurrentInstance())
|
|
316
|
-
query.select('.virtual-list').boundingClientRect((rect: any) => {
|
|
316
|
+
query.select('.im-virtual-list').boundingClientRect((rect: any) => {
|
|
317
317
|
if (rect && rect.height) {
|
|
318
318
|
containerHeight.value = rect.height
|
|
319
319
|
}
|
|
@@ -379,7 +379,7 @@ defineExpose({
|
|
|
379
379
|
</script>
|
|
380
380
|
|
|
381
381
|
<style lang="scss" scoped>
|
|
382
|
-
.virtual-list {
|
|
382
|
+
.im-virtual-list {
|
|
383
383
|
// min-height: 200rpx;
|
|
384
384
|
// height: 100vh;
|
|
385
385
|
}
|
package/package.json
CHANGED
|
@@ -1,58 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "im-ui-mobile",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A Vue3.0 + Typescript instant messaging component library for Uniapp",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "index.js",
|
|
7
|
-
"types": "types/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"components",
|
|
10
|
-
"libs",
|
|
11
|
-
"types",
|
|
12
|
-
"utils",
|
|
13
|
-
"plugins",
|
|
14
|
-
"index.js",
|
|
15
|
-
"styles",
|
|
16
|
-
"theme.scss",
|
|
17
|
-
"index.scss"
|
|
18
|
-
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"wx": "cd examples-dev && npm run dev:mp-weixin",
|
|
21
|
-
"h5": "cd examples-dev && npm run dev:h5",
|
|
22
|
-
"build": "npm run build:types",
|
|
23
|
-
"build:types": "vue-tsc -p tsconfig.build.json",
|
|
24
|
-
"clean:types": "rmdir /s /q src/types 2>nul # '删除 types 目录'",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@dcloudio/
|
|
29
|
-
"@dcloudio/
|
|
30
|
-
"@dcloudio/uni-cli-shared": "3.0.0-4070520250711001",
|
|
31
|
-
"@dcloudio/vite-plugin-uni": "3.0.0-4070520250711001",
|
|
32
|
-
"@types/node": "^24.10.1",
|
|
33
|
-
"@vitejs/plugin-vue": "^4.0.0",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "im-ui-mobile",
|
|
3
|
+
"version": "0.1.13",
|
|
4
|
+
"description": "A Vue3.0 + Typescript instant messaging component library for Uniapp",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "types/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"components",
|
|
10
|
+
"libs",
|
|
11
|
+
"types",
|
|
12
|
+
"utils",
|
|
13
|
+
"plugins",
|
|
14
|
+
"index.js",
|
|
15
|
+
"styles",
|
|
16
|
+
"theme.scss",
|
|
17
|
+
"index.scss"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"wx": "cd examples-dev && npm run dev:mp-weixin",
|
|
21
|
+
"h5": "cd examples-dev && npm run dev:h5",
|
|
22
|
+
"build": "npm run build:types",
|
|
23
|
+
"build:types": "vue-tsc -p tsconfig.build.json",
|
|
24
|
+
"clean:types": "rmdir /s /q src/types 2>nul # '删除 types 目录'",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@dcloudio/types": "^3.4.8",
|
|
29
|
+
"@dcloudio/uni-app": "3.0.0-4070520250711001",
|
|
30
|
+
"@dcloudio/uni-cli-shared": "3.0.0-4070520250711001",
|
|
31
|
+
"@dcloudio/vite-plugin-uni": "3.0.0-4070520250711001",
|
|
32
|
+
"@types/node": "^24.10.1",
|
|
33
|
+
"@vitejs/plugin-vue": "^4.0.0",
|
|
34
|
+
"sass": "^1.97.2",
|
|
35
|
+
"sass-loader": "^10.5.2",
|
|
36
|
+
"typescript": "~5.4.5",
|
|
37
|
+
"vite": "^4.0.0",
|
|
38
|
+
"vite-plugin-dts": "^3.0.0",
|
|
39
|
+
"vue-tsc": "^1.0.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@dcloudio/uni-app": "3.0.0-4070520250711001",
|
|
43
|
+
"pinia": "^2.1.7",
|
|
44
|
+
"vue": "^3.3.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"pinia": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"vue3",
|
|
53
|
+
"components",
|
|
54
|
+
"ui",
|
|
55
|
+
"instant-messaging",
|
|
56
|
+
"chat"
|
|
57
|
+
],
|
|
58
|
+
"author": "Joncky Cai",
|
|
59
|
+
"license": "MIT"
|
|
58
60
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// 将px转换为rpx
|
|
2
|
+
@function px2rpx($px) {
|
|
3
|
+
@return $px * 2rpx;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// 将rpx转换为px
|
|
7
|
+
@function rpx2px($rpx) {
|
|
8
|
+
@return $rpx / 2px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 计算rem
|
|
12
|
+
@function rem($px) {
|
|
13
|
+
@return $px / 16px * 1rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 颜色变亮
|
|
17
|
+
@function tint($color, $percentage) {
|
|
18
|
+
@return mix(white, $color, $percentage);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 颜色变暗
|
|
22
|
+
@function shade($color, $percentage) {
|
|
23
|
+
@return mix(black, $color, $percentage);
|
|
24
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// 文本溢出省略号
|
|
2
|
+
@mixin text-ellipsis($lines: 1) {
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
text-overflow: ellipsis;
|
|
5
|
+
|
|
6
|
+
@if $lines ==1 {
|
|
7
|
+
white-space: nowrap;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@else {
|
|
11
|
+
display: -webkit-box;
|
|
12
|
+
-webkit-line-clamp: $lines;
|
|
13
|
+
-webkit-box-orient: vertical;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 清除浮动
|
|
18
|
+
@mixin clearfix {
|
|
19
|
+
&::after {
|
|
20
|
+
content: '';
|
|
21
|
+
display: table;
|
|
22
|
+
clear: both;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 多行文本省略
|
|
27
|
+
@mixin multi-line-ellipsis($line-height: 1.4, $lines: 2) {
|
|
28
|
+
display: -webkit-box;
|
|
29
|
+
-webkit-box-orient: vertical;
|
|
30
|
+
-webkit-line-clamp: $lines;
|
|
31
|
+
line-height: $line-height;
|
|
32
|
+
max-height: $line-height * $lines * 1em;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 1像素边框
|
|
37
|
+
@mixin hairline($color: $border-base, $direction: bottom) {
|
|
38
|
+
position: relative;
|
|
39
|
+
|
|
40
|
+
&::after {
|
|
41
|
+
content: '';
|
|
42
|
+
position: absolute;
|
|
43
|
+
transform-origin: center;
|
|
44
|
+
box-sizing: border-box;
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
|
|
47
|
+
@if $direction ==top {
|
|
48
|
+
top: 0;
|
|
49
|
+
left: 0;
|
|
50
|
+
right: 0;
|
|
51
|
+
height: 1px;
|
|
52
|
+
border-top: 1px solid $color;
|
|
53
|
+
transform: scaleY(0.5);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@else if $direction ==bottom {
|
|
57
|
+
bottom: 0;
|
|
58
|
+
left: 0;
|
|
59
|
+
right: 0;
|
|
60
|
+
height: 1px;
|
|
61
|
+
border-bottom: 1px solid $color;
|
|
62
|
+
transform: scaleY(0.5);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@else if $direction ==left {
|
|
66
|
+
top: 0;
|
|
67
|
+
left: 0;
|
|
68
|
+
bottom: 0;
|
|
69
|
+
width: 1px;
|
|
70
|
+
border-left: 1px solid $color;
|
|
71
|
+
transform: scaleX(0.5);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@else if $direction ==right {
|
|
75
|
+
top: 0;
|
|
76
|
+
right: 0;
|
|
77
|
+
bottom: 0;
|
|
78
|
+
width: 1px;
|
|
79
|
+
border-right: 1px solid $color;
|
|
80
|
+
transform: scaleX(0.5);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@else if $direction ==all {
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
right: 0;
|
|
87
|
+
bottom: 0;
|
|
88
|
+
border: 1px solid $color;
|
|
89
|
+
transform: scale(0.5);
|
|
90
|
+
transform-origin: 0 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 移除1像素边框
|
|
96
|
+
@mixin hairline-remove {
|
|
97
|
+
&::after {
|
|
98
|
+
display: none;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 弹性布局快捷方式
|
|
103
|
+
@mixin flex($justify: flex-start, $align: center, $direction: row) {
|
|
104
|
+
display: flex;
|
|
105
|
+
flex-direction: $direction;
|
|
106
|
+
justify-content: $justify;
|
|
107
|
+
align-items: $align;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 垂直居中
|
|
111
|
+
@mixin vertical-center {
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 响应式媒体查询
|
|
118
|
+
@mixin respond-to($breakpoint) {
|
|
119
|
+
@if $breakpoint ==xs {
|
|
120
|
+
@media (max-width: 320px) {
|
|
121
|
+
@content;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@else if $breakpoint ==sm {
|
|
126
|
+
@media (max-width: 375px) {
|
|
127
|
+
@content;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@else if $breakpoint ==md {
|
|
132
|
+
@media (max-width: 414px) {
|
|
133
|
+
@content;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@else if $breakpoint ==lg {
|
|
138
|
+
@media (max-width: 768px) {
|
|
139
|
+
@content;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@else if $breakpoint ==xl {
|
|
144
|
+
@media (min-width: 1024px) {
|
|
145
|
+
@content;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// 颜色系统
|
|
2
|
+
$primary-color: #1989fa;
|
|
3
|
+
$success-color: #07c160;
|
|
4
|
+
$warning-color: #ff976a;
|
|
5
|
+
$danger-color: #ee0a24;
|
|
6
|
+
$info-color: #909399;
|
|
7
|
+
|
|
8
|
+
// 文本颜色
|
|
9
|
+
$text-primary: #303133;
|
|
10
|
+
$text-regular: #606266;
|
|
11
|
+
$text-secondary: #909399;
|
|
12
|
+
$text-placeholder: #c0c4cc;
|
|
13
|
+
|
|
14
|
+
// 边框颜色
|
|
15
|
+
$border-base: #dcdfe6;
|
|
16
|
+
$border-light: #e4e7ed;
|
|
17
|
+
$border-lighter: #ebeef5;
|
|
18
|
+
|
|
19
|
+
// 背景颜色
|
|
20
|
+
$bg-color: #f8f8f8;
|
|
21
|
+
$bg-color-light: #fafafa;
|
|
22
|
+
|
|
23
|
+
// 尺寸
|
|
24
|
+
$font-size-xs: 10px;
|
|
25
|
+
$font-size-sm: 12px;
|
|
26
|
+
$font-size-base: 14px;
|
|
27
|
+
$font-size-md: 16px;
|
|
28
|
+
$font-size-lg: 18px;
|
|
29
|
+
$font-size-xl: 20px;
|
|
30
|
+
|
|
31
|
+
// 间距
|
|
32
|
+
$spacing-xs: 4px;
|
|
33
|
+
$spacing-sm: 8px;
|
|
34
|
+
$spacing-base: 16px;
|
|
35
|
+
$spacing-md: 24px;
|
|
36
|
+
$spacing-lg: 32px;
|
|
37
|
+
$spacing-xl: 48px;
|
|
38
|
+
|
|
39
|
+
// 圆角
|
|
40
|
+
$border-radius-sm: 2px;
|
|
41
|
+
$border-radius-base: 4px;
|
|
42
|
+
$border-radius-md: 8px;
|
|
43
|
+
$border-radius-lg: 12px;
|
|
44
|
+
$border-radius-round: 20px;
|
|
45
|
+
$border-radius-circle: 50%;
|
|
46
|
+
|
|
47
|
+
// 阴影
|
|
48
|
+
$box-shadow-base: 0 2px 4px rgba(0, 0, 0, 0.12);
|
|
49
|
+
$box-shadow-light: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
50
|
+
|
|
51
|
+
// 动画
|
|
52
|
+
$transition-duration: 0.3s;
|
|
53
|
+
$transition-timing: ease;
|
|
54
|
+
|
|
55
|
+
// 深色模式变量
|
|
56
|
+
$dark-bg-color: #2a2a2a;
|
|
57
|
+
$dark-text-color: #ffffff;
|
|
58
|
+
$dark-border-color: #444444;
|