@zfqh/uview-x 0.0.0-stage → 0.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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +127 -3
- package/components/uv-badge/props.ts +83 -0
- package/components/uv-badge/uv-badge.vue +186 -0
- package/components/uv-button/props.ts +148 -0
- package/components/uv-button/uv-button.vue +565 -0
- package/components/uv-checkbox/props.ts +83 -0
- package/components/uv-checkbox/uv-checkbox.vue +403 -0
- package/components/uv-checkbox-group/props.ts +97 -0
- package/components/uv-checkbox-group/uv-checkbox-group.vue +163 -0
- package/components/uv-code/props.ts +48 -0
- package/components/uv-code/uv-code.vue +156 -0
- package/components/uv-dialog/props.ts +56 -0
- package/components/uv-dialog/uv-dialog.vue +492 -0
- package/components/uv-form/props.ts +59 -0
- package/components/uv-form/uv-form.vue +256 -0
- package/components/uv-form/valid.ts +1344 -0
- package/components/uv-form-item/props.ts +62 -0
- package/components/uv-form-item/uv-form-item.vue +335 -0
- package/components/uv-icon/icons.ts +161 -0
- package/components/uv-icon/props.ts +91 -0
- package/components/uv-icon/uv-icon.vue +208 -0
- package/components/uv-icon/uvicons.ttf +0 -0
- package/components/uv-input/props.ts +185 -0
- package/components/uv-input/uv-input.vue +431 -0
- package/components/uv-line/props.ts +42 -0
- package/components/uv-line/uv-line.vue +75 -0
- package/components/uv-line-progress/props.ts +43 -0
- package/components/uv-line-progress/uv-line-progress.vue +166 -0
- package/components/uv-loading-icon/props.ts +78 -0
- package/components/uv-loading-icon/uv-loading-icon.vue +226 -0
- package/components/uv-overlay/props.ts +38 -0
- package/components/uv-overlay/uv-overlay.vue +120 -0
- package/components/uv-popup/props.ts +101 -0
- package/components/uv-popup/uv-popup.vue +371 -0
- package/components/uv-safe-bottom/props.ts +18 -0
- package/components/uv-safe-bottom/uv-safe-bottom.vue +120 -0
- package/components/uv-status-bar/props.ts +22 -0
- package/components/uv-status-bar/uv-status-bar.vue +121 -0
- package/components/uv-tabs/props.ts +84 -0
- package/components/uv-tabs/uv-tabs.vue +432 -0
- package/components/uv-transition/props.ts +38 -0
- package/components/uv-transition/uv-transition.vue +170 -0
- package/hooks/index.ts +5 -0
- package/hooks/useDebounce.ts +35 -0
- package/hooks/useI18n.ts +95 -0
- package/hooks/useThrottle.ts +38 -0
- package/index.ts +23 -0
- package/libs/dayjs/index.ts +217 -0
- package/libs/index.ts +4 -0
- package/libs/luch-request/adapters/index.ts +133 -0
- package/libs/luch-request/core/InterceptorManager.ts +52 -0
- package/libs/luch-request/core/Request.ts +202 -0
- package/libs/luch-request/core/buildFullPath.ts +21 -0
- package/libs/luch-request/core/defaults.ts +34 -0
- package/libs/luch-request/core/dispatchRequest.ts +7 -0
- package/libs/luch-request/core/mergeConfig.ts +127 -0
- package/libs/luch-request/core/settle.ts +17 -0
- package/libs/luch-request/helpers/buildURL.ts +65 -0
- package/libs/luch-request/helpers/combineURLs.ts +15 -0
- package/libs/luch-request/helpers/isAbsoluteURL.ts +15 -0
- package/libs/luch-request/index.d.ts +197 -0
- package/libs/luch-request/index.ts +3 -0
- package/libs/luch-request/utils/clone.ts +265 -0
- package/libs/luch-request/utils.ts +136 -0
- package/locales/en.ts +78 -0
- package/locales/index.ts +169 -0
- package/locales/zh-Hans.ts +78 -0
- package/package.json +42 -4
- package/styles/color.scss +33 -0
- package/styles/common.scss +134 -0
- package/styles/components.scss +19 -0
- package/styles/index.scss +7 -0
- package/styles/theme.scss +44 -0
- package/styles/var.module.scss +32 -0
- package/styles/vue.scss +39 -0
- package/theme.scss +2 -0
- package/types/index.d.ts +66 -0
- package/utils/colorGradient.ts +139 -0
- package/utils/compat.ts +165 -0
- package/utils/compress.ts +34 -0
- package/utils/config.ts +95 -0
- package/utils/debounce.ts +7 -0
- package/utils/digit.ts +157 -0
- package/utils/function.ts +771 -0
- package/utils/http.ts +5 -0
- package/utils/index.ts +57 -0
- package/utils/locale.ts +296 -0
- package/utils/platform.ts +71 -0
- package/utils/route.ts +142 -0
- package/utils/test.ts +256 -0
- package/utils/throttle.ts +7 -0
package/locales/index.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { I18nMessages } from '../utils/locale';
|
|
2
|
+
import zhHans from './zh-Hans';
|
|
3
|
+
import en from './en';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* uview-x 组件内置语言包与合并工具。
|
|
7
|
+
*
|
|
8
|
+
* - 纯数据 / 纯函数模块:不 import `vue` / `vue-i18n`,避免与 `utils/locale.ts` 形成值循环;
|
|
9
|
+
* - 组件内置文案统一使用 `uv.*` 键空间,用户可在 `createI18n({ messages })` 中按同名 key 覆盖;
|
|
10
|
+
* - 用户未创建 i18n 实例时,`utils/locale.ts` 的 `appTranslate` 会回退到这里的内置语言包。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** 语言包节点:字符串,或继续嵌套的语言包对象 */
|
|
14
|
+
export type LocaleMessageValue = string | LocaleMessages;
|
|
15
|
+
|
|
16
|
+
/** 单语言语言包 */
|
|
17
|
+
export interface LocaleMessages {
|
|
18
|
+
[key: string]: LocaleMessageValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 组件内置语言包:locale → 语言包 */
|
|
22
|
+
export const componentMessages: Record<string, LocaleMessages> = {
|
|
23
|
+
'zh-Hans': zhHans,
|
|
24
|
+
en,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function isLocaleMessages(value: LocaleMessageValue | undefined): value is LocaleMessages {
|
|
28
|
+
return typeof value === 'object' && value !== null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 深拷贝语言包节点,保证合并过程不修改内置 / 用户入参 */
|
|
32
|
+
function cloneMessageValue(value: LocaleMessageValue): LocaleMessageValue {
|
|
33
|
+
if (!isLocaleMessages(value)) {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
const cloned: LocaleMessages = {};
|
|
37
|
+
for (const key of Object.keys(value)) {
|
|
38
|
+
cloned[key] = cloneMessageValue(value[key]);
|
|
39
|
+
}
|
|
40
|
+
return cloned;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** 深合并「内置 → 用户」:同名 key 用户覆盖,对象逐层合并,其余保留 */
|
|
44
|
+
function mergeMessages(builtinMessages: LocaleMessages, userMessages: LocaleMessages): LocaleMessages {
|
|
45
|
+
const merged: LocaleMessages = {};
|
|
46
|
+
for (const key of Object.keys(builtinMessages)) {
|
|
47
|
+
merged[key] = cloneMessageValue(builtinMessages[key]);
|
|
48
|
+
}
|
|
49
|
+
for (const key of Object.keys(userMessages)) {
|
|
50
|
+
const builtinValue = merged[key];
|
|
51
|
+
const userValue = userMessages[key];
|
|
52
|
+
if (isLocaleMessages(builtinValue) && isLocaleMessages(userValue)) {
|
|
53
|
+
merged[key] = mergeMessages(builtinValue, userValue);
|
|
54
|
+
} else {
|
|
55
|
+
merged[key] = cloneMessageValue(userValue);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return merged;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 把组件内置语言包合并进用户 messages(返回新对象,不修改入参)。
|
|
63
|
+
*
|
|
64
|
+
* - 内置已有的 locale(`zh-Hans` / `en`)逐层深合并,用户同名 key 优先;
|
|
65
|
+
* - 用户额外传入的 locale 原样保留;
|
|
66
|
+
* - 用户未传 messages 时返回内置语言包副本。
|
|
67
|
+
*/
|
|
68
|
+
export function mergeComponentMessages(userMessages?: I18nMessages): I18nMessages {
|
|
69
|
+
const locales: string[] = Object.keys(componentMessages);
|
|
70
|
+
if (userMessages) {
|
|
71
|
+
for (const locale of Object.keys(userMessages)) {
|
|
72
|
+
if (locales.indexOf(locale) === -1) {
|
|
73
|
+
locales.push(locale);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const merged: I18nMessages = {};
|
|
78
|
+
for (const locale of locales) {
|
|
79
|
+
const builtinMessages = componentMessages[locale] || {};
|
|
80
|
+
const userLocaleMessages = userMessages ? userMessages[locale] : undefined;
|
|
81
|
+
merged[locale] = mergeMessages(builtinMessages, isLocaleMessages(userLocaleMessages) ? userLocaleMessages : {});
|
|
82
|
+
}
|
|
83
|
+
return merged;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** 按 `a.b.c` 路径取字符串消息;非字符串 / 不存在返回空字符串 */
|
|
87
|
+
function getMessageByPath(messages: LocaleMessages, key: string): string {
|
|
88
|
+
const segments = String(key).split('.');
|
|
89
|
+
let current: LocaleMessageValue | undefined = messages;
|
|
90
|
+
for (const segment of segments) {
|
|
91
|
+
if (current === undefined || typeof current === 'string') {
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
current = current[segment];
|
|
95
|
+
}
|
|
96
|
+
return typeof current === 'string' ? current : '';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 替换 `{name}` 占位符(App 端没有 vue-i18n 编译能力,需要手动替换) */
|
|
100
|
+
function replacePlaceholders(str: string, values?: Record<string, string | number>): string {
|
|
101
|
+
if (!values || typeof str !== 'string') {
|
|
102
|
+
return str;
|
|
103
|
+
}
|
|
104
|
+
let out = str;
|
|
105
|
+
for (const key of Object.keys(values)) {
|
|
106
|
+
out = out.split(`{${key}}`).join(String(values[key]));
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 读取组件内置文案;按 `a.b.c` 路径查找并替换 `{name}` 占位符。
|
|
113
|
+
*
|
|
114
|
+
* 找不到时返回空字符串,由调用方(`appTranslate`)继续回退到 key。
|
|
115
|
+
*/
|
|
116
|
+
export function getBuiltinMessage(locale: string, key: string, values?: Record<string, string | number>): string {
|
|
117
|
+
const messages = componentMessages[locale];
|
|
118
|
+
if (!messages) {
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
return replacePlaceholders(getMessageByPath(messages, key), values);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 用 `t` 构建 async-validator 的校验消息对象(结构与 `components/uv-form/valid.ts` 的 `newMessages()` 对齐)。
|
|
126
|
+
*
|
|
127
|
+
* 显式 `rules[].message` 仍由校验器优先使用;这里只提供默认文案。
|
|
128
|
+
*/
|
|
129
|
+
export function buildFormValidationMessages(t: (key: string) => string): Record<string, unknown> {
|
|
130
|
+
const typeMessage = (type: string): string => t(`uv.form.types.${type}`);
|
|
131
|
+
const lengthMessages = (type: string): Record<string, string> => ({
|
|
132
|
+
len: t(`uv.form.${type}.len`),
|
|
133
|
+
min: t(`uv.form.${type}.min`),
|
|
134
|
+
max: t(`uv.form.${type}.max`),
|
|
135
|
+
range: t(`uv.form.${type}.range`),
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
default: t('uv.form.default'),
|
|
139
|
+
required: t('uv.form.required'),
|
|
140
|
+
enum: t('uv.form.enum'),
|
|
141
|
+
whitespace: t('uv.form.whitespace'),
|
|
142
|
+
date: {
|
|
143
|
+
format: t('uv.form.date.format'),
|
|
144
|
+
parse: t('uv.form.date.parse'),
|
|
145
|
+
invalid: t('uv.form.date.invalid'),
|
|
146
|
+
},
|
|
147
|
+
types: {
|
|
148
|
+
string: typeMessage('string'),
|
|
149
|
+
method: typeMessage('method'),
|
|
150
|
+
array: typeMessage('array'),
|
|
151
|
+
object: typeMessage('object'),
|
|
152
|
+
number: typeMessage('number'),
|
|
153
|
+
date: typeMessage('date'),
|
|
154
|
+
boolean: typeMessage('boolean'),
|
|
155
|
+
integer: typeMessage('integer'),
|
|
156
|
+
float: typeMessage('float'),
|
|
157
|
+
regexp: typeMessage('regexp'),
|
|
158
|
+
email: typeMessage('email'),
|
|
159
|
+
url: typeMessage('url'),
|
|
160
|
+
hex: typeMessage('hex'),
|
|
161
|
+
},
|
|
162
|
+
string: lengthMessages('string'),
|
|
163
|
+
number: lengthMessages('number'),
|
|
164
|
+
array: lengthMessages('array'),
|
|
165
|
+
pattern: {
|
|
166
|
+
mismatch: t('uv.form.pattern.mismatch'),
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 组件内置语言包:简体中文(zh-Hans)。
|
|
3
|
+
*
|
|
4
|
+
* 键空间固定为 `uv.*`,用户可通过 `createI18n({ messages })` 传同名 key 覆盖;
|
|
5
|
+
* `uv.form.*` 与 `components/uv-form/valid.ts` 的 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
6
|
+
*/
|
|
7
|
+
const zhHans = {
|
|
8
|
+
uv: {
|
|
9
|
+
dialog: {
|
|
10
|
+
title: '提示',
|
|
11
|
+
cancel: '取消',
|
|
12
|
+
confirm: '确定',
|
|
13
|
+
},
|
|
14
|
+
code: {
|
|
15
|
+
start: '获取验证码',
|
|
16
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
17
|
+
change: 'X秒重新获取',
|
|
18
|
+
end: '重新获取',
|
|
19
|
+
},
|
|
20
|
+
time: {
|
|
21
|
+
justNow: '刚刚',
|
|
22
|
+
minutesAgo: '{n}分钟前',
|
|
23
|
+
hoursAgo: '{n}小时前',
|
|
24
|
+
daysAgo: '{n}天前',
|
|
25
|
+
monthsAgo: '{n}个月前',
|
|
26
|
+
yearsAgo: '{n}年前',
|
|
27
|
+
},
|
|
28
|
+
form: {
|
|
29
|
+
default: '%s 校验失败',
|
|
30
|
+
required: '%s 是必填项',
|
|
31
|
+
enum: '%s 必须是 %s 之一',
|
|
32
|
+
whitespace: '%s 不能为空',
|
|
33
|
+
date: {
|
|
34
|
+
format: '%s 的日期 %s 格式 %s 无效',
|
|
35
|
+
parse: '%s 的日期无法解析,%s 无效',
|
|
36
|
+
invalid: '%s 的日期 %s 无效',
|
|
37
|
+
},
|
|
38
|
+
types: {
|
|
39
|
+
string: '%s 不是 %s 类型',
|
|
40
|
+
method: '%s 不是 %s 类型',
|
|
41
|
+
array: '%s 不是 %s 类型',
|
|
42
|
+
object: '%s 不是 %s 类型',
|
|
43
|
+
number: '%s 不是 %s 类型',
|
|
44
|
+
date: '%s 不是 %s 类型',
|
|
45
|
+
boolean: '%s 不是 %s 类型',
|
|
46
|
+
integer: '%s 不是 %s 类型',
|
|
47
|
+
float: '%s 不是 %s 类型',
|
|
48
|
+
regexp: '%s 不是有效的 %s 类型',
|
|
49
|
+
email: '%s 不是有效的 %s 类型',
|
|
50
|
+
url: '%s 不是有效的 %s 类型',
|
|
51
|
+
hex: '%s 不是有效的 %s 类型',
|
|
52
|
+
},
|
|
53
|
+
string: {
|
|
54
|
+
len: '%s 长度必须为 %s 个字符',
|
|
55
|
+
min: '%s 至少为 %s 个字符',
|
|
56
|
+
max: '%s 不能超过 %s 个字符',
|
|
57
|
+
range: '%s 长度必须在 %s 到 %s 个字符之间',
|
|
58
|
+
},
|
|
59
|
+
number: {
|
|
60
|
+
len: '%s 必须等于 %s',
|
|
61
|
+
min: '%s 不能小于 %s',
|
|
62
|
+
max: '%s 不能大于 %s',
|
|
63
|
+
range: '%s 必须在 %s 到 %s 之间',
|
|
64
|
+
},
|
|
65
|
+
array: {
|
|
66
|
+
len: '%s 长度必须为 %s',
|
|
67
|
+
min: '%s 长度不能小于 %s',
|
|
68
|
+
max: '%s 长度不能大于 %s',
|
|
69
|
+
range: '%s 长度必须在 %s 到 %s 之间',
|
|
70
|
+
},
|
|
71
|
+
pattern: {
|
|
72
|
+
mismatch: '%s 的值 %s 不匹配格式 %s',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default zhHans;
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zfqh/uview-x",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "uview-x:面向 uni-app x 蒸汽模式(Vapor)、经典 uni-app Vue3 与 nvue 的 UV UI 组件库,组件保持 uv-ui API。",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"vue-i18n": "9.1.9"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"uv-ui",
|
|
16
|
+
"uvui",
|
|
17
|
+
"uni-app 框架",
|
|
18
|
+
"uv_UI",
|
|
19
|
+
"uv UI",
|
|
20
|
+
"uni-app x",
|
|
21
|
+
"uni-app-x",
|
|
22
|
+
"uni-app vue3",
|
|
23
|
+
"nvue",
|
|
24
|
+
"app-plus",
|
|
25
|
+
"vapor",
|
|
26
|
+
"蒸汽模式"
|
|
27
|
+
],
|
|
28
|
+
"author": "yinjiazeng@163.com",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"files": [
|
|
31
|
+
"components",
|
|
32
|
+
"hooks",
|
|
33
|
+
"libs",
|
|
34
|
+
"locales",
|
|
35
|
+
"styles",
|
|
36
|
+
"types",
|
|
37
|
+
"utils",
|
|
38
|
+
"index.ts",
|
|
39
|
+
"theme.scss",
|
|
40
|
+
"README.md",
|
|
41
|
+
"CHANGELOG.md"
|
|
42
|
+
],
|
|
43
|
+
"gitHead": "abcec16d4c73e83cec02770a553cd89091e35cf3"
|
|
44
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
$uv-main-color: #333333 !default;
|
|
2
|
+
$uv-content-color: #7a7a7a !default;
|
|
3
|
+
$uv-tips-color: #9a9a9a !default;
|
|
4
|
+
$uv-light-color: #c0c4cc !default;
|
|
5
|
+
$uv-border-color: #eeeeee !default;
|
|
6
|
+
$uv-bg-color: #f5f5f5 !default;
|
|
7
|
+
$uv-bg-light-color: #fffbf4 !default;
|
|
8
|
+
$uv-disabled-color: #c8c9cc !default;
|
|
9
|
+
|
|
10
|
+
$uv-primary: #00b4c3 !default;
|
|
11
|
+
$uv-primary-dark: #157572 !default;
|
|
12
|
+
$uv-primary-disabled: #b4e3d9 !default;
|
|
13
|
+
$uv-primary-light: #dff3f9 !default;
|
|
14
|
+
|
|
15
|
+
$uv-warning: #ff9a05 !default;
|
|
16
|
+
$uv-warning-dark: #ed6c04 !default;
|
|
17
|
+
$uv-warning-disabled: #f9d39b !default;
|
|
18
|
+
$uv-warning-light: #fdf6ec !default;
|
|
19
|
+
|
|
20
|
+
$uv-success: #5ac725 !default;
|
|
21
|
+
$uv-success-dark: #53c21d !default;
|
|
22
|
+
$uv-success-disabled: #a9e08f !default;
|
|
23
|
+
$uv-success-light: #f5fff0 !default;
|
|
24
|
+
|
|
25
|
+
$uv-error: #ff4d4f !default;
|
|
26
|
+
$uv-error-dark: #e45656 !default;
|
|
27
|
+
$uv-error-disabled: #f7b2b2 !default;
|
|
28
|
+
$uv-error-light: #fef0f0 !default;
|
|
29
|
+
|
|
30
|
+
$uv-info: #909399 !default;
|
|
31
|
+
$uv-info-dark: #767a82 !default;
|
|
32
|
+
$uv-info-disabled: #c4c6c9 !default;
|
|
33
|
+
$uv-info-light: #f4f4f5 !default;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// 全局工具类(x-safe)。
|
|
2
|
+
//
|
|
3
|
+
// App 蒸汽模式只支持 class / 分组 / 复合 class / page 选择器,
|
|
4
|
+
// 因此这里不使用元素选择器、伪类、伪元素;Web/小程序专属规则放在条件块中。
|
|
5
|
+
|
|
6
|
+
// 超出行数,自动显示行尾省略号,最多 5 行
|
|
7
|
+
// App 蒸汽模式用 text 的 max-lines;nvue 用 weex 的 lines;Web/小程序用 CSS 截断。
|
|
8
|
+
/* #ifdef APP-NVUE */
|
|
9
|
+
@for $i from 1 through 5 {
|
|
10
|
+
.uv-line-#{$i} {
|
|
11
|
+
lines: $i;
|
|
12
|
+
text-overflow: ellipsis;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
flex: 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/* #endif */
|
|
18
|
+
|
|
19
|
+
/* #ifdef WEB || H5 || MP */
|
|
20
|
+
@for $i from 1 through 5 {
|
|
21
|
+
.uv-line-#{$i} {
|
|
22
|
+
@if $i == 1 {
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
white-space: nowrap;
|
|
25
|
+
text-overflow: ellipsis;
|
|
26
|
+
} @else {
|
|
27
|
+
display: -webkit-box !important;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
text-overflow: ellipsis;
|
|
30
|
+
word-break: break-all;
|
|
31
|
+
-webkit-line-clamp: $i;
|
|
32
|
+
-webkit-box-orient: vertical !important;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/* #endif */
|
|
37
|
+
|
|
38
|
+
$uv-bordercolor: #dadbde !default;
|
|
39
|
+
@if variable-exists(uv-border-color) {
|
|
40
|
+
$uv-bordercolor: $uv-border-color;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 边框工具类:
|
|
44
|
+
// - nvue 不支持 !important,基础声明供 App-NVUE 使用;
|
|
45
|
+
// - Web/H5/MP 与 App 蒸汽模式保留 !important 覆盖组件内联边框(与上游行为一致)。
|
|
46
|
+
.uv-border {
|
|
47
|
+
border-style: solid;
|
|
48
|
+
border-width: 0.5px;
|
|
49
|
+
border-color: $uv-bordercolor;
|
|
50
|
+
/* #ifndef APP-NVUE */
|
|
51
|
+
border-width: 0.5px !important;
|
|
52
|
+
border-color: $uv-bordercolor !important;
|
|
53
|
+
/* #endif */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.uv-border-top {
|
|
57
|
+
border-top-style: solid;
|
|
58
|
+
border-top-width: 0.5px;
|
|
59
|
+
border-color: $uv-bordercolor;
|
|
60
|
+
/* #ifndef APP-NVUE */
|
|
61
|
+
border-top-width: 0.5px !important;
|
|
62
|
+
border-color: $uv-bordercolor !important;
|
|
63
|
+
/* #endif */
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.uv-border-left {
|
|
67
|
+
border-left-style: solid;
|
|
68
|
+
border-left-width: 0.5px;
|
|
69
|
+
border-color: $uv-bordercolor;
|
|
70
|
+
/* #ifndef APP-NVUE */
|
|
71
|
+
border-left-width: 0.5px !important;
|
|
72
|
+
border-color: $uv-bordercolor !important;
|
|
73
|
+
/* #endif */
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.uv-border-right {
|
|
77
|
+
border-right-style: solid;
|
|
78
|
+
border-right-width: 0.5px;
|
|
79
|
+
border-color: $uv-bordercolor;
|
|
80
|
+
/* #ifndef APP-NVUE */
|
|
81
|
+
border-right-width: 0.5px !important;
|
|
82
|
+
border-color: $uv-bordercolor !important;
|
|
83
|
+
/* #endif */
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.uv-border-bottom {
|
|
87
|
+
border-bottom-style: solid;
|
|
88
|
+
border-bottom-width: 0.5px;
|
|
89
|
+
border-color: $uv-bordercolor;
|
|
90
|
+
/* #ifndef APP-NVUE */
|
|
91
|
+
border-bottom-width: 0.5px !important;
|
|
92
|
+
border-color: $uv-bordercolor !important;
|
|
93
|
+
/* #endif */
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.uv-border-top-bottom {
|
|
97
|
+
border-top-style: solid;
|
|
98
|
+
border-bottom-style: solid;
|
|
99
|
+
border-top-width: 0.5px;
|
|
100
|
+
border-bottom-width: 0.5px;
|
|
101
|
+
border-color: $uv-bordercolor;
|
|
102
|
+
/* #ifndef APP-NVUE */
|
|
103
|
+
border-top-width: 0.5px !important;
|
|
104
|
+
border-bottom-width: 0.5px !important;
|
|
105
|
+
border-color: $uv-bordercolor !important;
|
|
106
|
+
/* #endif */
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 去除 button 默认样式,让其表现跟普通 view/text 一致
|
|
110
|
+
// 注意:App 蒸汽模式不支持 font-size/line-height/color: inherit,这里给显式兜底值,
|
|
111
|
+
// 组件内部会通过内联样式/局部 class 覆盖。
|
|
112
|
+
.uv-reset-button {
|
|
113
|
+
padding: 0;
|
|
114
|
+
background-color: transparent;
|
|
115
|
+
/* #ifndef APP-NVUE */
|
|
116
|
+
border-width: 0;
|
|
117
|
+
font-size: 16px;
|
|
118
|
+
line-height: 20px;
|
|
119
|
+
color: #303133;
|
|
120
|
+
/* #endif */
|
|
121
|
+
/* #ifdef APP-NVUE */
|
|
122
|
+
border-width: 0;
|
|
123
|
+
/* #endif */
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* #ifdef WEB || H5 || MP */
|
|
127
|
+
.uv-reset-button::after {
|
|
128
|
+
border: none;
|
|
129
|
+
}
|
|
130
|
+
/* #endif */
|
|
131
|
+
|
|
132
|
+
.uv-hover-class {
|
|
133
|
+
opacity: 0.7;
|
|
134
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// uview-x 组件样式基础 mixin。
|
|
2
|
+
//
|
|
3
|
+
// 注意:这里只允许输出“编译期可消解”的 SCSS 或扁平 class 规则。
|
|
4
|
+
// uni-app x App 蒸汽模式不支持元素选择器、后代选择器、伪类/伪元素,
|
|
5
|
+
// 因此原 uv-ui 中的 view/scroll-view 全局重置必须放在 index.scss 的
|
|
6
|
+
// WEB / MP 条件块中,不能出现在每个组件的 style 里。
|
|
7
|
+
@mixin flex($direction: row) {
|
|
8
|
+
/* #ifndef APP-NVUE */
|
|
9
|
+
display: flex;
|
|
10
|
+
/* #endif */
|
|
11
|
+
flex-direction: $direction;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 细边框(用于需要显式声明边框的场景,调用方自行控制 class)
|
|
15
|
+
@mixin border-1px($color: #dadbde) {
|
|
16
|
+
border-width: 0.5px;
|
|
17
|
+
border-color: $color;
|
|
18
|
+
border-style: solid;
|
|
19
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// 此文件为uvUI的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于
|
|
2
|
+
// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大,
|
|
3
|
+
// 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入
|
|
4
|
+
|
|
5
|
+
$uv-main-color: #303133;
|
|
6
|
+
$uv-content-color: #606266;
|
|
7
|
+
$uv-tips-color: #909193;
|
|
8
|
+
$uv-light-color: #c0c4cc;
|
|
9
|
+
$uv-border-color: #dadbde;
|
|
10
|
+
$uv-bg-color: #f3f4f6;
|
|
11
|
+
$uv-bg-light-color: #fffbf4;
|
|
12
|
+
$uv-disabled-color: #c8c9cc;
|
|
13
|
+
|
|
14
|
+
$uv-primary: #3c9cff;
|
|
15
|
+
$uv-primary-dark: #398ade;
|
|
16
|
+
$uv-primary-disabled: #9acafc;
|
|
17
|
+
$uv-primary-light: #ecf5ff;
|
|
18
|
+
|
|
19
|
+
$uv-warning: #f9ae3d;
|
|
20
|
+
$uv-warning-dark: #f1a532;
|
|
21
|
+
$uv-warning-disabled: #f9d39b;
|
|
22
|
+
$uv-warning-light: #fdf6ec;
|
|
23
|
+
|
|
24
|
+
$uv-success: #5ac725;
|
|
25
|
+
$uv-success-dark: #53c21d;
|
|
26
|
+
$uv-success-disabled: #a9e08f;
|
|
27
|
+
$uv-success-light: #f5fff0;
|
|
28
|
+
|
|
29
|
+
$uv-error: #f56c6c;
|
|
30
|
+
$uv-error-dark: #e45656;
|
|
31
|
+
$uv-error-disabled: #f7b2b2;
|
|
32
|
+
$uv-error-light: #fef0f0;
|
|
33
|
+
|
|
34
|
+
$uv-info: #909399;
|
|
35
|
+
$uv-info-dark: #767a82;
|
|
36
|
+
$uv-info-disabled: #c4c6c9;
|
|
37
|
+
$uv-info-light: #f4f4f5;
|
|
38
|
+
|
|
39
|
+
@mixin flex($direction: row) {
|
|
40
|
+
/* #ifndef APP-NVUE */
|
|
41
|
+
display: flex;
|
|
42
|
+
/* #endif */
|
|
43
|
+
flex-direction: $direction;
|
|
44
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@import './color.scss';
|
|
2
|
+
|
|
3
|
+
:export {
|
|
4
|
+
primary: $uv-primary;
|
|
5
|
+
primaryDark: $uv-primary-dark;
|
|
6
|
+
primaryDisabled: $uv-primary-disabled;
|
|
7
|
+
primaryLight: $uv-primary-light;
|
|
8
|
+
success: $uv-success;
|
|
9
|
+
successDark: $uv-success-dark;
|
|
10
|
+
successDisabled: $uv-success-disabled;
|
|
11
|
+
successLight: $uv-success-light;
|
|
12
|
+
warning: $uv-warning;
|
|
13
|
+
warningDark: $uv-warning-dark;
|
|
14
|
+
warningDisabled: $uv-warning-disabled;
|
|
15
|
+
warningLight: $uv-warning-light;
|
|
16
|
+
error: $uv-error;
|
|
17
|
+
errorDark: $uv-error-dark;
|
|
18
|
+
errorDisabled: $uv-error-disabled;
|
|
19
|
+
errorLight: $uv-error-light;
|
|
20
|
+
info: $uv-info;
|
|
21
|
+
infoDark: $uv-info-dark;
|
|
22
|
+
infoDisabled: $uv-info-disabled;
|
|
23
|
+
infoLight: $uv-info-light;
|
|
24
|
+
bgColor: $uv-bg-color;
|
|
25
|
+
bgLightColor: $uv-bg-light-color;
|
|
26
|
+
mainColor: $uv-main-color;
|
|
27
|
+
contentColor: $uv-content-color;
|
|
28
|
+
tipsColor: $uv-tips-color;
|
|
29
|
+
lightColor: $uv-light-color;
|
|
30
|
+
disabledColor: $uv-disabled-color;
|
|
31
|
+
borderColor: $uv-border-color;
|
|
32
|
+
}
|
package/styles/vue.scss
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// 全局辅助样式(x-safe)。
|
|
2
|
+
//
|
|
3
|
+
// App 蒸汽模式不支持元素选择器、伪元素、后代选择器;
|
|
4
|
+
// Web/小程序不需要这些限制,相关规则保留在条件编译块中。
|
|
5
|
+
|
|
6
|
+
// 四个方向的安全区
|
|
7
|
+
@each $d in top, right, bottom, left {
|
|
8
|
+
.uv-safe-area-inset-#{$d} {
|
|
9
|
+
padding-#{$d}: 0;
|
|
10
|
+
/* #ifdef APP */
|
|
11
|
+
padding-#{$d}: var(--uni-safe-area-inset-#{$d}, 0px);
|
|
12
|
+
/* #endif */
|
|
13
|
+
/* #ifdef WEB || H5 || MP */
|
|
14
|
+
padding-#{$d}: constant(safe-area-inset-#{$d});
|
|
15
|
+
padding-#{$d}: env(safe-area-inset-#{$d});
|
|
16
|
+
/* #endif */
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* #ifdef WEB || H5 */
|
|
21
|
+
// 提升 H5 端 uni.toast() 的层级,避免被弹层遮盖
|
|
22
|
+
uni-toast {
|
|
23
|
+
z-index: 10090;
|
|
24
|
+
}
|
|
25
|
+
uni-toast .uni-toast {
|
|
26
|
+
z-index: 10090;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 隐藏 scroll-view 滚动条
|
|
30
|
+
::-webkit-scrollbar {
|
|
31
|
+
display: none;
|
|
32
|
+
width: 0 !important;
|
|
33
|
+
height: 0 !important;
|
|
34
|
+
-webkit-appearance: none;
|
|
35
|
+
background: transparent;
|
|
36
|
+
}
|
|
37
|
+
/* #endif */
|
|
38
|
+
|
|
39
|
+
|
package/theme.scss
ADDED
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zfqh/uview-x 全局注入类型声明。
|
|
3
|
+
*
|
|
4
|
+
* 入口 `index.ts` 会把 `$uv` 挂到 `uni.$uv` 与 `app.config.globalProperties.$uv`;
|
|
5
|
+
* `utils/locale.ts` 的 `createI18n` 会把 i18n 实例挂到 `uni.$i18n`。
|
|
6
|
+
* 本文件为 uni 全局对象与 Vue 组件实例补充类型,并声明入口默认插件类型与 i18n 公共 API。
|
|
7
|
+
*/
|
|
8
|
+
import type { App } from 'vue';
|
|
9
|
+
import type { I18n, I18nOptions } from 'vue-i18n';
|
|
10
|
+
|
|
11
|
+
type UviewX$uv = (typeof import('../utils'))['$uv'];
|
|
12
|
+
|
|
13
|
+
declare global {
|
|
14
|
+
namespace UniNamespace {
|
|
15
|
+
interface GetAppBaseInfoResult {
|
|
16
|
+
/** uni-app x App 返回的语言,如 en / zh-Hans / zh-Hant / fr / es(经典端用 language 兜底) */
|
|
17
|
+
appLanguage?: string;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Uni {
|
|
22
|
+
$uv: UviewX$uv;
|
|
23
|
+
/** `createI18n` 创建的全局 i18n 实例 */
|
|
24
|
+
$i18n?: I18n;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare module '*.ttf' {
|
|
29
|
+
const src: string;
|
|
30
|
+
export default src;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module '*.otf' {
|
|
34
|
+
const src: string;
|
|
35
|
+
export default src;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare module 'vue' {
|
|
39
|
+
interface ComponentCustomProperties {
|
|
40
|
+
$uv: UviewX$uv;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 入口模块声明:包内 `types` 指向本文件时,消费者仍可从入口
|
|
46
|
+
* `import { config, createI18n, useI18n, setLocale, ... } from '@zfqh/uview-x'` 获得类型提示。
|
|
47
|
+
*
|
|
48
|
+
* 这里声明 `config` 与 4 个 i18n 公共函数 + `useI18n`;包内其余 helper、内部状态与 default/fallback 语言均不对外导出。
|
|
49
|
+
*/
|
|
50
|
+
declare module '@zfqh/uview-x' {
|
|
51
|
+
/** 运行时配置;颜色通过 `config.color` 访问(键为 camelCase,如 `primary`) */
|
|
52
|
+
export const config: (typeof import('../utils'))['config'];
|
|
53
|
+
/** 创建 i18n 实例并挂到 `uni.$i18n`(自动合并 `locales/` 内置组件语言包,用户同名 key 覆盖) */
|
|
54
|
+
export function createI18n(opts: I18nOptions): I18n;
|
|
55
|
+
/** 获取当前语言(storage `UNI_LOCALE` → `uni.getLocale` → `getAppBaseInfo` → `zh-Hans`) */
|
|
56
|
+
export function getLocale(): string;
|
|
57
|
+
/** 按当前语言取词(优先全局语言包,其次组件内置语言包;支持 `a.b.c` 路径与 `{name}` 占位符) */
|
|
58
|
+
export function getLocaleMessage(key: string, values?: Record<string, string | number>): string;
|
|
59
|
+
/** 设置当前语言:更新内部 localeState 与 `uni.$i18n.global.locale`,写 storage `UNI_LOCALE`,最后调用 `uni.setLocale` */
|
|
60
|
+
export function setLocale(locale: string): void;
|
|
61
|
+
/** i18n hook:未创建 i18n 实例时降级读组件内置语言包,不会抛错 */
|
|
62
|
+
export const useI18n: typeof import('vue-i18n').useI18n;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare const plugin: { install: (app: App) => void };
|
|
66
|
+
export default plugin;
|