@zfqh/uview-x 0.0.6 → 0.0.7
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 +8 -0
- package/README.md +52 -9
- package/components/uv-badge/uv-badge.vue +4 -4
- package/components/uv-button/uv-button.vue +10 -10
- package/components/uv-checkbox/uv-checkbox.vue +11 -9
- package/components/uv-checkbox-group/uv-checkbox-group.vue +2 -2
- package/components/uv-code/uv-code.vue +2 -2
- package/components/uv-dialog/uv-dialog.vue +11 -10
- package/components/uv-form/uv-form.vue +244 -246
- package/components/uv-form-item/uv-form-item.vue +10 -9
- package/components/uv-icon/uv-icon.vue +13 -13
- package/components/uv-input/uv-input.vue +6 -5
- package/components/uv-line/uv-line.vue +7 -6
- package/components/uv-line-progress/uv-line-progress.vue +5 -5
- package/components/uv-loading-icon/uv-loading-icon.vue +9 -8
- package/components/uv-overlay/uv-overlay.vue +3 -2
- package/components/uv-popup/uv-popup.vue +7 -5
- package/components/uv-safe-bottom/uv-safe-bottom.vue +4 -3
- package/components/uv-status-bar/uv-status-bar.vue +4 -3
- package/components/uv-tabs/uv-tabs.vue +15 -12
- package/components/uv-transition/uv-transition.vue +2 -2
- package/hooks/index.ts +5 -5
- package/hooks/useDebounce.ts +33 -35
- package/hooks/useI18n.ts +4 -3
- package/hooks/useThrottle.ts +36 -38
- package/index.ts +50 -29
- package/locales/en.ts +56 -0
- package/locales/es.ts +57 -0
- package/locales/fr.ts +57 -0
- package/locales/index.ts +15 -159
- package/locales/ru.ts +57 -0
- package/locales/zh-Hans.ts +57 -0
- package/locales/zh-Hant.ts +57 -0
- package/package.json +2 -2
- package/types/index.d.ts +68 -59
- package/utils/color.ts +139 -0
- package/utils/compress.ts +28 -28
- package/utils/config.ts +45 -10
- package/utils/debounce.ts +4 -4
- package/utils/function.ts +2 -87
- package/utils/locale.ts +444 -270
- package/utils/merge.ts +74 -0
- package/utils/platform.ts +28 -28
- package/utils/route.ts +123 -129
- package/utils/scrollbar.ts +19 -19
- package/utils/throttle.ts +4 -4
- package/locales/en-US.ts +0 -79
- package/locales/es-ES.ts +0 -79
- package/locales/fr-FR.ts +0 -79
- package/locales/ru-RU.ts +0 -79
- package/locales/zh-CN.ts +0 -79
- package/locales/zh-TW.ts +0 -79
- package/utils/colorGradient.ts +0 -139
- package/utils/index.ts +0 -58
package/index.ts
CHANGED
|
@@ -1,30 +1,51 @@
|
|
|
1
|
-
import type { App } from 'vue';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import type { App } from 'vue';
|
|
2
|
+
import config, { setConfig } from './utils/config';
|
|
3
|
+
import type { UViewConfigOptions, UViewColor, UViewConfig } from './utils/config';
|
|
4
|
+
import type { UViewCompressOptions } from './utils/compress';
|
|
5
|
+
import * as test from './utils/test';
|
|
6
|
+
import { createI18n, getLocale, getLocaleMessage, setLocale } from './utils/locale';
|
|
7
|
+
import type { UViewI18nMessages, UViewCreateI18nOptions, UViewI18nOptions } from './utils/locale';
|
|
8
|
+
// #ifdef WEB || H5
|
|
9
|
+
import { applyScrollbar } from './utils/scrollbar';
|
|
10
|
+
// #endif
|
|
11
|
+
|
|
12
|
+
export * from './hooks';
|
|
13
|
+
export * from './utils/route';
|
|
14
|
+
|
|
15
|
+
export { default as compress } from './utils/compress';
|
|
16
|
+
export { default as debounce } from './utils/debounce';
|
|
17
|
+
export { default as http } from './utils/http';
|
|
18
|
+
export { default as throttle } from './utils/throttle';
|
|
19
|
+
export { test };
|
|
20
|
+
|
|
21
|
+
export { config, setConfig };
|
|
22
|
+
export type { UViewCompressOptions, UViewConfigOptions, UViewColor, UViewConfig };
|
|
23
|
+
|
|
24
|
+
export { createI18n, getLocale, getLocaleMessage, setLocale };
|
|
25
|
+
export type { UViewI18nMessages, UViewCreateI18nOptions, UViewI18nOptions };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* uview-x 插件。
|
|
29
|
+
*
|
|
30
|
+
* - `app.use(UviewX, options)`:安装时应用初始化配置(runtime config + i18n);
|
|
31
|
+
* - `app.use(UviewX)`:使用此前 `setConfig` 的配置或默认值;
|
|
32
|
+
* - 不向 app / uni 注入任何全局对象;
|
|
33
|
+
* - H5 下按 `config.scrollbar` 注入全局滚动条样式(默认隐藏)。
|
|
21
34
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
export interface UViewPlugin {
|
|
36
|
+
install(app: App, options?: UViewConfigOptions): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const plugin: UViewPlugin = {
|
|
40
|
+
install(app: App, options?: UViewConfigOptions): void {
|
|
41
|
+
void app;
|
|
42
|
+
if (options) {
|
|
43
|
+
setConfig(options);
|
|
44
|
+
}
|
|
45
|
+
// #ifdef WEB || H5
|
|
46
|
+
applyScrollbar(config.scrollbar);
|
|
47
|
+
// #endif
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default plugin;
|
package/locales/en.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 默认组件语言包:英文(en),也是组件内置默认语言。
|
|
3
|
+
*
|
|
4
|
+
* 内部由 `utils/locale.ts` 聚合;`createI18n` 会自动注入并允许同名扁平 key 覆盖。
|
|
5
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
6
|
+
*/
|
|
7
|
+
const en = {
|
|
8
|
+
'uv.dialog.title': 'Tips',
|
|
9
|
+
'uv.dialog.cancel': 'Cancel',
|
|
10
|
+
'uv.dialog.confirm': 'OK',
|
|
11
|
+
'uv.code.start': 'Get code',
|
|
12
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
13
|
+
'uv.code.change': 'X seconds to resend',
|
|
14
|
+
'uv.code.end': 'Resend',
|
|
15
|
+
'uv.time.justNow': 'Just now',
|
|
16
|
+
'uv.time.minutesAgo': '{n} minutes ago',
|
|
17
|
+
'uv.time.hoursAgo': '{n} hours ago',
|
|
18
|
+
'uv.time.daysAgo': '{n} days ago',
|
|
19
|
+
'uv.time.monthsAgo': '{n} months ago',
|
|
20
|
+
'uv.time.yearsAgo': '{n} years ago',
|
|
21
|
+
'uv.form.default': 'Validation error on field %s',
|
|
22
|
+
'uv.form.required': '%s is required',
|
|
23
|
+
'uv.form.enum': '%s must be one of %s',
|
|
24
|
+
'uv.form.whitespace': '%s cannot be empty',
|
|
25
|
+
'uv.form.date.format': '%s date %s is invalid for format %s',
|
|
26
|
+
'uv.form.date.parse': '%s date could not be parsed, %s is invalid',
|
|
27
|
+
'uv.form.date.invalid': '%s date %s is invalid',
|
|
28
|
+
'uv.form.types.string': '%s is not a %s',
|
|
29
|
+
'uv.form.types.method': '%s is not a %s (function)',
|
|
30
|
+
'uv.form.types.array': '%s is not an %s',
|
|
31
|
+
'uv.form.types.object': '%s is not an %s',
|
|
32
|
+
'uv.form.types.number': '%s is not a %s',
|
|
33
|
+
'uv.form.types.date': '%s is not a %s',
|
|
34
|
+
'uv.form.types.boolean': '%s is not a %s',
|
|
35
|
+
'uv.form.types.integer': '%s is not an %s',
|
|
36
|
+
'uv.form.types.float': '%s is not a %s',
|
|
37
|
+
'uv.form.types.regexp': '%s is not a valid %s',
|
|
38
|
+
'uv.form.types.email': '%s is not a valid %s',
|
|
39
|
+
'uv.form.types.url': '%s is not a valid %s',
|
|
40
|
+
'uv.form.types.hex': '%s is not a valid %s',
|
|
41
|
+
'uv.form.string.len': '%s must be exactly %s characters',
|
|
42
|
+
'uv.form.string.min': '%s must be at least %s characters',
|
|
43
|
+
'uv.form.string.max': '%s cannot be longer than %s characters',
|
|
44
|
+
'uv.form.string.range': '%s must be between %s and %s characters',
|
|
45
|
+
'uv.form.number.len': '%s must equal %s',
|
|
46
|
+
'uv.form.number.min': '%s cannot be less than %s',
|
|
47
|
+
'uv.form.number.max': '%s cannot be greater than %s',
|
|
48
|
+
'uv.form.number.range': '%s must be between %s and %s',
|
|
49
|
+
'uv.form.array.len': '%s must be exactly %s in length',
|
|
50
|
+
'uv.form.array.min': '%s cannot be less than %s in length',
|
|
51
|
+
'uv.form.array.max': '%s cannot be greater than %s in length',
|
|
52
|
+
'uv.form.array.range': '%s must be between %s and %s in length',
|
|
53
|
+
'uv.form.pattern.mismatch': '%s value %s does not match pattern %s',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default en;
|
package/locales/es.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 可选组件语言包:西班牙语(es)。
|
|
3
|
+
*
|
|
4
|
+
* 不参与内部聚合、不会被 `createI18n` 自动合并;需要西班牙语时由使用方显式引入并合并:
|
|
5
|
+
* `import es from '@zfqh/uview-x/locales/es'`,再在 `createI18n({ messages: { es } })` 中使用。
|
|
6
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
7
|
+
*/
|
|
8
|
+
const es = {
|
|
9
|
+
'uv.dialog.title': 'Consejo',
|
|
10
|
+
'uv.dialog.cancel': 'Cancelar',
|
|
11
|
+
'uv.dialog.confirm': 'Confirmar',
|
|
12
|
+
'uv.code.start': 'Obtener código',
|
|
13
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
14
|
+
'uv.code.change': 'X segundos para reenviar',
|
|
15
|
+
'uv.code.end': 'Reenviar',
|
|
16
|
+
'uv.time.justNow': 'Ahora mismo',
|
|
17
|
+
'uv.time.minutesAgo': 'hace {n} minutos',
|
|
18
|
+
'uv.time.hoursAgo': 'hace {n} horas',
|
|
19
|
+
'uv.time.daysAgo': 'hace {n} días',
|
|
20
|
+
'uv.time.monthsAgo': 'hace {n} meses',
|
|
21
|
+
'uv.time.yearsAgo': 'hace {n} años',
|
|
22
|
+
'uv.form.default': 'Error de validación en el campo %s',
|
|
23
|
+
'uv.form.required': '%s es obligatorio',
|
|
24
|
+
'uv.form.enum': '%s debe ser uno de %s',
|
|
25
|
+
'uv.form.whitespace': '%s no puede estar vacío',
|
|
26
|
+
'uv.form.date.format': '%s la fecha %s no es válida para el formato %s',
|
|
27
|
+
'uv.form.date.parse': '%s no se pudo analizar la fecha, %s no es válido',
|
|
28
|
+
'uv.form.date.invalid': '%s la fecha %s no es válida',
|
|
29
|
+
'uv.form.types.string': '%s no es de tipo %s',
|
|
30
|
+
'uv.form.types.method': '%s no es de tipo %s (función)',
|
|
31
|
+
'uv.form.types.array': '%s no es de tipo %s',
|
|
32
|
+
'uv.form.types.object': '%s no es de tipo %s',
|
|
33
|
+
'uv.form.types.number': '%s no es de tipo %s',
|
|
34
|
+
'uv.form.types.date': '%s no es de tipo %s',
|
|
35
|
+
'uv.form.types.boolean': '%s no es de tipo %s',
|
|
36
|
+
'uv.form.types.integer': '%s no es de tipo %s',
|
|
37
|
+
'uv.form.types.float': '%s no es de tipo %s',
|
|
38
|
+
'uv.form.types.regexp': '%s no es un %s válido',
|
|
39
|
+
'uv.form.types.email': '%s no es un %s válido',
|
|
40
|
+
'uv.form.types.url': '%s no es un %s válido',
|
|
41
|
+
'uv.form.types.hex': '%s no es un %s válido',
|
|
42
|
+
'uv.form.string.len': '%s debe tener exactamente %s caracteres',
|
|
43
|
+
'uv.form.string.min': '%s debe tener al menos %s caracteres',
|
|
44
|
+
'uv.form.string.max': '%s no puede tener más de %s caracteres',
|
|
45
|
+
'uv.form.string.range': '%s debe tener entre %s y %s caracteres',
|
|
46
|
+
'uv.form.number.len': '%s debe ser igual a %s',
|
|
47
|
+
'uv.form.number.min': '%s no puede ser menor que %s',
|
|
48
|
+
'uv.form.number.max': '%s no puede ser mayor que %s',
|
|
49
|
+
'uv.form.number.range': '%s debe estar entre %s y %s',
|
|
50
|
+
'uv.form.array.len': '%s debe tener exactamente %s elementos',
|
|
51
|
+
'uv.form.array.min': '%s no puede tener menos de %s elementos',
|
|
52
|
+
'uv.form.array.max': '%s no puede tener más de %s elementos',
|
|
53
|
+
'uv.form.array.range': '%s debe tener entre %s y %s elementos',
|
|
54
|
+
'uv.form.pattern.mismatch': '%s el valor %s no coincide con el patrón %s',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default es;
|
package/locales/fr.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 可选组件语言包:法语(fr)。
|
|
3
|
+
*
|
|
4
|
+
* 不参与内部聚合、不会被 `createI18n` 自动合并;需要法语时由使用方显式引入并合并:
|
|
5
|
+
* `import fr from '@zfqh/uview-x/locales/fr'`,再在 `createI18n({ messages: { fr } })` 中使用。
|
|
6
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
7
|
+
*/
|
|
8
|
+
const fr = {
|
|
9
|
+
'uv.dialog.title': 'Conseil',
|
|
10
|
+
'uv.dialog.cancel': 'Annuler',
|
|
11
|
+
'uv.dialog.confirm': 'Confirmer',
|
|
12
|
+
'uv.code.start': 'Obtenir le code',
|
|
13
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
14
|
+
'uv.code.change': 'X secondes avant de renvoyer',
|
|
15
|
+
'uv.code.end': 'Renvoyer',
|
|
16
|
+
'uv.time.justNow': "À l'instant",
|
|
17
|
+
'uv.time.minutesAgo': 'il y a {n} minutes',
|
|
18
|
+
'uv.time.hoursAgo': 'il y a {n} heures',
|
|
19
|
+
'uv.time.daysAgo': 'il y a {n} jours',
|
|
20
|
+
'uv.time.monthsAgo': 'il y a {n} mois',
|
|
21
|
+
'uv.time.yearsAgo': 'il y a {n} ans',
|
|
22
|
+
'uv.form.default': 'Erreur de validation du champ %s',
|
|
23
|
+
'uv.form.required': '%s est requis',
|
|
24
|
+
'uv.form.enum': "%s doit être l'un de %s",
|
|
25
|
+
'uv.form.whitespace': '%s ne peut pas être vide',
|
|
26
|
+
'uv.form.date.format': "%s la date %s n'est pas valide pour le format %s",
|
|
27
|
+
'uv.form.date.parse': "%s la date n'a pas pu être analysée, %s n'est pas valide",
|
|
28
|
+
'uv.form.date.invalid': "%s la date %s n'est pas valide",
|
|
29
|
+
'uv.form.types.string': "%s n'est pas de type %s",
|
|
30
|
+
'uv.form.types.method': "%s n'est pas de type %s (fonction)",
|
|
31
|
+
'uv.form.types.array': "%s n'est pas de type %s",
|
|
32
|
+
'uv.form.types.object': "%s n'est pas de type %s",
|
|
33
|
+
'uv.form.types.number': "%s n'est pas de type %s",
|
|
34
|
+
'uv.form.types.date': "%s n'est pas de type %s",
|
|
35
|
+
'uv.form.types.boolean': "%s n'est pas de type %s",
|
|
36
|
+
'uv.form.types.integer': "%s n'est pas de type %s",
|
|
37
|
+
'uv.form.types.float': "%s n'est pas de type %s",
|
|
38
|
+
'uv.form.types.regexp': "%s n'est pas un %s valide",
|
|
39
|
+
'uv.form.types.email': "%s n'est pas un %s valide",
|
|
40
|
+
'uv.form.types.url': "%s n'est pas un %s valide",
|
|
41
|
+
'uv.form.types.hex': "%s n'est pas un %s valide",
|
|
42
|
+
'uv.form.string.len': '%s doit contenir exactement %s caractères',
|
|
43
|
+
'uv.form.string.min': '%s doit contenir au moins %s caractères',
|
|
44
|
+
'uv.form.string.max': '%s ne peut pas dépasser %s caractères',
|
|
45
|
+
'uv.form.string.range': '%s doit contenir entre %s et %s caractères',
|
|
46
|
+
'uv.form.number.len': '%s doit être égal à %s',
|
|
47
|
+
'uv.form.number.min': '%s ne peut pas être inférieur à %s',
|
|
48
|
+
'uv.form.number.max': '%s ne peut pas être supérieur à %s',
|
|
49
|
+
'uv.form.number.range': '%s doit être compris entre %s et %s',
|
|
50
|
+
'uv.form.array.len': '%s doit contenir exactement %s éléments',
|
|
51
|
+
'uv.form.array.min': '%s ne peut pas contenir moins de %s éléments',
|
|
52
|
+
'uv.form.array.max': '%s ne peut pas contenir plus de %s éléments',
|
|
53
|
+
'uv.form.array.range': '%s doit contenir entre %s et %s éléments',
|
|
54
|
+
'uv.form.pattern.mismatch': '%s la valeur %s ne correspond pas au motif %s',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default fr;
|
package/locales/index.ts
CHANGED
|
@@ -1,166 +1,22 @@
|
|
|
1
|
-
import type { I18nMessages } from '../utils/locale';
|
|
2
|
-
import zhCN from './zh-CN';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
|
-
* uview-x
|
|
2
|
+
* uview-x 语言包聚合入口(仅语言数据,不含组件 i18n 聚合逻辑)。
|
|
6
3
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* - 用户未创建 i18n 实例时,`utils/locale.ts` 的 `appTranslate` 会回退到这里的中文默认语言包。
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/** 语言包节点:字符串,或继续嵌套的语言包对象 */
|
|
15
|
-
export type LocaleMessageValue = string | LocaleMessages;
|
|
16
|
-
|
|
17
|
-
/** 单语言语言包 */
|
|
18
|
-
export interface LocaleMessages {
|
|
19
|
-
[key: string]: LocaleMessageValue;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** 内部聚合的默认组件语言包:仅 `zh-CN`(其他语言按需从 `locales/<locale>.ts` 引入) */
|
|
23
|
-
export const componentMessages: Record<string, LocaleMessages> = {
|
|
24
|
-
'zh-CN': zhCN,
|
|
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
|
-
* 把默认语言(`zh-CN`)合并进用户 messages(返回新对象,不修改入参)。
|
|
4
|
+
* 使用方可自行选择:
|
|
5
|
+
* - `import { en, zhHans } from '@zfqh/uview-x/locales'`;
|
|
6
|
+
* - `import locales from '@zfqh/uview-x/locales'`(默认对象);
|
|
7
|
+
* - `import en from '@zfqh/uview-x/locales/en'`。
|
|
63
8
|
*
|
|
64
|
-
*
|
|
65
|
-
* - 用户传入的其他 locale(如自行合并的 `en-US`)原样保留,不做补全或内置合并;
|
|
66
|
-
* - 用户未传 messages 时返回仅含中文默认语言包的副本。
|
|
9
|
+
* 组件内置默认语言为 `en`;该入口不会被包根入口 re-export。
|
|
67
10
|
*/
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for (const locale of Object.keys(userMessages)) {
|
|
75
|
-
if (locale !== 'zh-CN') {
|
|
76
|
-
merged[locale] = userMessages[locale];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return merged;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** 按 `a.b.c` 路径取字符串消息;非字符串 / 不存在返回空字符串 */
|
|
84
|
-
function getMessageByPath(messages: LocaleMessages, key: string): string {
|
|
85
|
-
const segments = String(key).split('.');
|
|
86
|
-
let current: LocaleMessageValue | undefined = messages;
|
|
87
|
-
for (const segment of segments) {
|
|
88
|
-
if (current === undefined || typeof current === 'string') {
|
|
89
|
-
return '';
|
|
90
|
-
}
|
|
91
|
-
current = current[segment];
|
|
92
|
-
}
|
|
93
|
-
return typeof current === 'string' ? current : '';
|
|
94
|
-
}
|
|
11
|
+
import en from './en';
|
|
12
|
+
import zhHans from './zh-Hans';
|
|
13
|
+
import zhHant from './zh-Hant';
|
|
14
|
+
import es from './es';
|
|
15
|
+
import fr from './fr';
|
|
16
|
+
import ru from './ru';
|
|
95
17
|
|
|
96
|
-
|
|
97
|
-
function replacePlaceholders(str: string, values?: Record<string, string | number>): string {
|
|
98
|
-
if (!values || typeof str !== 'string') {
|
|
99
|
-
return str;
|
|
100
|
-
}
|
|
101
|
-
let out = str;
|
|
102
|
-
for (const key of Object.keys(values)) {
|
|
103
|
-
out = out.split(`{${key}}`).join(String(values[key]));
|
|
104
|
-
}
|
|
105
|
-
return out;
|
|
106
|
-
}
|
|
18
|
+
export { en, zhHans, zhHant, es, fr, ru };
|
|
107
19
|
|
|
108
|
-
|
|
109
|
-
* 读取默认中文文案;按 `a.b.c` 路径查找并替换 `{name}` 占位符。
|
|
110
|
-
*
|
|
111
|
-
* 找不到时返回空字符串,由调用方(`appTranslate`)继续回退到 key。
|
|
112
|
-
*/
|
|
113
|
-
export function getBuiltinMessage(locale: string, key: string, values?: Record<string, string | number>): string {
|
|
114
|
-
const messages = componentMessages[locale];
|
|
115
|
-
if (!messages) {
|
|
116
|
-
return '';
|
|
117
|
-
}
|
|
118
|
-
return replacePlaceholders(getMessageByPath(messages, key), values);
|
|
119
|
-
}
|
|
20
|
+
const locales = { en, zhHans, zhHant, es, fr, ru };
|
|
120
21
|
|
|
121
|
-
|
|
122
|
-
* 用 `t` 构建 async-validator 的校验消息对象(结构与 `components/uv-form/valid.ts` 的 `newMessages()` 对齐)。
|
|
123
|
-
*
|
|
124
|
-
* 显式 `rules[].message` 仍由校验器优先使用;这里只提供默认文案。
|
|
125
|
-
*/
|
|
126
|
-
export function buildFormValidationMessages(t: (key: string) => string): Record<string, unknown> {
|
|
127
|
-
const typeMessage = (type: string): string => t(`uv.form.types.${type}`);
|
|
128
|
-
const lengthMessages = (type: string): Record<string, string> => ({
|
|
129
|
-
len: t(`uv.form.${type}.len`),
|
|
130
|
-
min: t(`uv.form.${type}.min`),
|
|
131
|
-
max: t(`uv.form.${type}.max`),
|
|
132
|
-
range: t(`uv.form.${type}.range`),
|
|
133
|
-
});
|
|
134
|
-
return {
|
|
135
|
-
default: t('uv.form.default'),
|
|
136
|
-
required: t('uv.form.required'),
|
|
137
|
-
enum: t('uv.form.enum'),
|
|
138
|
-
whitespace: t('uv.form.whitespace'),
|
|
139
|
-
date: {
|
|
140
|
-
format: t('uv.form.date.format'),
|
|
141
|
-
parse: t('uv.form.date.parse'),
|
|
142
|
-
invalid: t('uv.form.date.invalid'),
|
|
143
|
-
},
|
|
144
|
-
types: {
|
|
145
|
-
string: typeMessage('string'),
|
|
146
|
-
method: typeMessage('method'),
|
|
147
|
-
array: typeMessage('array'),
|
|
148
|
-
object: typeMessage('object'),
|
|
149
|
-
number: typeMessage('number'),
|
|
150
|
-
date: typeMessage('date'),
|
|
151
|
-
boolean: typeMessage('boolean'),
|
|
152
|
-
integer: typeMessage('integer'),
|
|
153
|
-
float: typeMessage('float'),
|
|
154
|
-
regexp: typeMessage('regexp'),
|
|
155
|
-
email: typeMessage('email'),
|
|
156
|
-
url: typeMessage('url'),
|
|
157
|
-
hex: typeMessage('hex'),
|
|
158
|
-
},
|
|
159
|
-
string: lengthMessages('string'),
|
|
160
|
-
number: lengthMessages('number'),
|
|
161
|
-
array: lengthMessages('array'),
|
|
162
|
-
pattern: {
|
|
163
|
-
mismatch: t('uv.form.pattern.mismatch'),
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
22
|
+
export default locales;
|
package/locales/ru.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 可选组件语言包:俄语(ru)。
|
|
3
|
+
*
|
|
4
|
+
* 不参与内部聚合、不会被 `createI18n` 自动合并;需要俄语时由使用方显式引入并合并:
|
|
5
|
+
* `import ru from '@zfqh/uview-x/locales/ru'`,再在 `createI18n({ messages: { ru } })` 中使用。
|
|
6
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
7
|
+
*/
|
|
8
|
+
const ru = {
|
|
9
|
+
'uv.dialog.title': 'Подсказка',
|
|
10
|
+
'uv.dialog.cancel': 'Отмена',
|
|
11
|
+
'uv.dialog.confirm': 'Подтвердить',
|
|
12
|
+
'uv.code.start': 'Получить код',
|
|
13
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
14
|
+
'uv.code.change': 'Повторная отправка через X секунд',
|
|
15
|
+
'uv.code.end': 'Отправить повторно',
|
|
16
|
+
'uv.time.justNow': 'Только что',
|
|
17
|
+
'uv.time.minutesAgo': '{n} мин. назад',
|
|
18
|
+
'uv.time.hoursAgo': '{n} ч. назад',
|
|
19
|
+
'uv.time.daysAgo': '{n} дн. назад',
|
|
20
|
+
'uv.time.monthsAgo': '{n} мес. назад',
|
|
21
|
+
'uv.time.yearsAgo': '{n} г. назад',
|
|
22
|
+
'uv.form.default': 'Ошибка проверки поля %s',
|
|
23
|
+
'uv.form.required': '%s обязательно для заполнения',
|
|
24
|
+
'uv.form.enum': '%s должно быть одним из %s',
|
|
25
|
+
'uv.form.whitespace': '%s не может быть пустым',
|
|
26
|
+
'uv.form.date.format': '%s дата %s недействительна для формата %s',
|
|
27
|
+
'uv.form.date.parse': '%s не удалось разобрать дату, %s недействительна',
|
|
28
|
+
'uv.form.date.invalid': '%s дата %s недействительна',
|
|
29
|
+
'uv.form.types.string': '%s не является типом %s',
|
|
30
|
+
'uv.form.types.method': '%s не является типом %s (функция)',
|
|
31
|
+
'uv.form.types.array': '%s не является типом %s',
|
|
32
|
+
'uv.form.types.object': '%s не является типом %s',
|
|
33
|
+
'uv.form.types.number': '%s не является типом %s',
|
|
34
|
+
'uv.form.types.date': '%s не является типом %s',
|
|
35
|
+
'uv.form.types.boolean': '%s не является типом %s',
|
|
36
|
+
'uv.form.types.integer': '%s не является типом %s',
|
|
37
|
+
'uv.form.types.float': '%s не является типом %s',
|
|
38
|
+
'uv.form.types.regexp': '%s не является допустимым %s',
|
|
39
|
+
'uv.form.types.email': '%s не является допустимым %s',
|
|
40
|
+
'uv.form.types.url': '%s не является допустимым %s',
|
|
41
|
+
'uv.form.types.hex': '%s не является допустимым %s',
|
|
42
|
+
'uv.form.string.len': 'Длина %s должна быть ровно %s символов',
|
|
43
|
+
'uv.form.string.min': 'Длина %s должна быть не менее %s символов',
|
|
44
|
+
'uv.form.string.max': 'Длина %s не должна превышать %s символов',
|
|
45
|
+
'uv.form.string.range': 'Длина %s должна быть от %s до %s символов',
|
|
46
|
+
'uv.form.number.len': '%s должно быть равно %s',
|
|
47
|
+
'uv.form.number.min': '%s не может быть меньше %s',
|
|
48
|
+
'uv.form.number.max': '%s не может быть больше %s',
|
|
49
|
+
'uv.form.number.range': '%s должно быть между %s и %s',
|
|
50
|
+
'uv.form.array.len': 'Длина %s должна быть ровно %s элементов',
|
|
51
|
+
'uv.form.array.min': 'Длина %s должна быть не меньше %s элементов',
|
|
52
|
+
'uv.form.array.max': 'Длина %s не должна превышать %s элементов',
|
|
53
|
+
'uv.form.array.range': 'Длина %s должна быть от %s до %s элементов',
|
|
54
|
+
'uv.form.pattern.mismatch': '%s значение %s не соответствует шаблону %s',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default ru;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 可选组件语言包:简体中文(zh-Hans)。
|
|
3
|
+
*
|
|
4
|
+
* 不参与内部聚合、不会被 `createI18n` 自动合并;需要简体中文时由使用方显式引入并合并:
|
|
5
|
+
* `import zhHans from '@zfqh/uview-x/locales/zh-Hans'`,再在 `createI18n({ messages: { 'zh-Hans': zhHans } })` 中使用。
|
|
6
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
7
|
+
*/
|
|
8
|
+
const zhHans = {
|
|
9
|
+
'uv.dialog.title': '提示',
|
|
10
|
+
'uv.dialog.cancel': '取消',
|
|
11
|
+
'uv.dialog.confirm': '确定',
|
|
12
|
+
'uv.code.start': '获取验证码',
|
|
13
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
14
|
+
'uv.code.change': 'X秒重新获取',
|
|
15
|
+
'uv.code.end': '重新获取',
|
|
16
|
+
'uv.time.justNow': '刚刚',
|
|
17
|
+
'uv.time.minutesAgo': '{n}分钟前',
|
|
18
|
+
'uv.time.hoursAgo': '{n}小时前',
|
|
19
|
+
'uv.time.daysAgo': '{n}天前',
|
|
20
|
+
'uv.time.monthsAgo': '{n}个月前',
|
|
21
|
+
'uv.time.yearsAgo': '{n}年前',
|
|
22
|
+
'uv.form.default': '%s 校验失败',
|
|
23
|
+
'uv.form.required': '%s 是必填项',
|
|
24
|
+
'uv.form.enum': '%s 必须是 %s 之一',
|
|
25
|
+
'uv.form.whitespace': '%s 不能为空',
|
|
26
|
+
'uv.form.date.format': '%s 的日期 %s 格式 %s 无效',
|
|
27
|
+
'uv.form.date.parse': '%s 的日期无法解析,%s 无效',
|
|
28
|
+
'uv.form.date.invalid': '%s 的日期 %s 无效',
|
|
29
|
+
'uv.form.types.string': '%s 不是 %s 类型',
|
|
30
|
+
'uv.form.types.method': '%s 不是 %s 类型',
|
|
31
|
+
'uv.form.types.array': '%s 不是 %s 类型',
|
|
32
|
+
'uv.form.types.object': '%s 不是 %s 类型',
|
|
33
|
+
'uv.form.types.number': '%s 不是 %s 类型',
|
|
34
|
+
'uv.form.types.date': '%s 不是 %s 类型',
|
|
35
|
+
'uv.form.types.boolean': '%s 不是 %s 类型',
|
|
36
|
+
'uv.form.types.integer': '%s 不是 %s 类型',
|
|
37
|
+
'uv.form.types.float': '%s 不是 %s 类型',
|
|
38
|
+
'uv.form.types.regexp': '%s 不是有效的 %s 类型',
|
|
39
|
+
'uv.form.types.email': '%s 不是有效的 %s 类型',
|
|
40
|
+
'uv.form.types.url': '%s 不是有效的 %s 类型',
|
|
41
|
+
'uv.form.types.hex': '%s 不是有效的 %s 类型',
|
|
42
|
+
'uv.form.string.len': '%s 长度必须为 %s 个字符',
|
|
43
|
+
'uv.form.string.min': '%s 至少为 %s 个字符',
|
|
44
|
+
'uv.form.string.max': '%s 不能超过 %s 个字符',
|
|
45
|
+
'uv.form.string.range': '%s 长度必须在 %s 到 %s 个字符之间',
|
|
46
|
+
'uv.form.number.len': '%s 必须等于 %s',
|
|
47
|
+
'uv.form.number.min': '%s 不能小于 %s',
|
|
48
|
+
'uv.form.number.max': '%s 不能大于 %s',
|
|
49
|
+
'uv.form.number.range': '%s 必须在 %s 到 %s 之间',
|
|
50
|
+
'uv.form.array.len': '%s 长度必须为 %s',
|
|
51
|
+
'uv.form.array.min': '%s 长度不能小于 %s',
|
|
52
|
+
'uv.form.array.max': '%s 长度不能大于 %s',
|
|
53
|
+
'uv.form.array.range': '%s 长度必须在 %s 到 %s 之间',
|
|
54
|
+
'uv.form.pattern.mismatch': '%s 的值 %s 不匹配格式 %s',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default zhHans;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uview-x 可选组件语言包:繁体中文(zh-Hant)。
|
|
3
|
+
*
|
|
4
|
+
* 不参与内部聚合、不会被 `createI18n` 自动合并;需要繁体中文时由使用方显式引入并合并:
|
|
5
|
+
* `import zhHant from '@zfqh/uview-x/locales/zh-Hant'`,再在 `createI18n({ messages: { 'zh-Hant': zhHant } })` 中使用。
|
|
6
|
+
* 键空间固定为扁平 `uv.*`,`uv.form.*` 与 async-validator 默认 messages 对齐,`%s` 占位符由校验器替换。
|
|
7
|
+
*/
|
|
8
|
+
const zhHant = {
|
|
9
|
+
'uv.dialog.title': '提示',
|
|
10
|
+
'uv.dialog.cancel': '取消',
|
|
11
|
+
'uv.dialog.confirm': '確定',
|
|
12
|
+
'uv.code.start': '取得驗證碼',
|
|
13
|
+
// 组件会把 x / X 替换为剩余秒数
|
|
14
|
+
'uv.code.change': 'X秒重新取得',
|
|
15
|
+
'uv.code.end': '重新取得',
|
|
16
|
+
'uv.time.justNow': '剛剛',
|
|
17
|
+
'uv.time.minutesAgo': '{n}分鐘前',
|
|
18
|
+
'uv.time.hoursAgo': '{n}小時前',
|
|
19
|
+
'uv.time.daysAgo': '{n}天前',
|
|
20
|
+
'uv.time.monthsAgo': '{n}個月前',
|
|
21
|
+
'uv.time.yearsAgo': '{n}年前',
|
|
22
|
+
'uv.form.default': '%s 驗證失敗',
|
|
23
|
+
'uv.form.required': '%s 為必填項',
|
|
24
|
+
'uv.form.enum': '%s 必須是 %s 之一',
|
|
25
|
+
'uv.form.whitespace': '%s 不能為空',
|
|
26
|
+
'uv.form.date.format': '%s 的日期 %s 格式 %s 無效',
|
|
27
|
+
'uv.form.date.parse': '%s 的日期無法解析,%s 無效',
|
|
28
|
+
'uv.form.date.invalid': '%s 的日期 %s 無效',
|
|
29
|
+
'uv.form.types.string': '%s 不是 %s 類型',
|
|
30
|
+
'uv.form.types.method': '%s 不是 %s 類型',
|
|
31
|
+
'uv.form.types.array': '%s 不是 %s 類型',
|
|
32
|
+
'uv.form.types.object': '%s 不是 %s 類型',
|
|
33
|
+
'uv.form.types.number': '%s 不是 %s 類型',
|
|
34
|
+
'uv.form.types.date': '%s 不是 %s 類型',
|
|
35
|
+
'uv.form.types.boolean': '%s 不是 %s 類型',
|
|
36
|
+
'uv.form.types.integer': '%s 不是 %s 類型',
|
|
37
|
+
'uv.form.types.float': '%s 不是 %s 類型',
|
|
38
|
+
'uv.form.types.regexp': '%s 不是有效的 %s 類型',
|
|
39
|
+
'uv.form.types.email': '%s 不是有效的 %s 類型',
|
|
40
|
+
'uv.form.types.url': '%s 不是有效的 %s 類型',
|
|
41
|
+
'uv.form.types.hex': '%s 不是有效的 %s 類型',
|
|
42
|
+
'uv.form.string.len': '%s 長度必須為 %s 個字元',
|
|
43
|
+
'uv.form.string.min': '%s 至少為 %s 個字元',
|
|
44
|
+
'uv.form.string.max': '%s 不能超過 %s 個字元',
|
|
45
|
+
'uv.form.string.range': '%s 長度必須在 %s 到 %s 個字元之間',
|
|
46
|
+
'uv.form.number.len': '%s 必須等於 %s',
|
|
47
|
+
'uv.form.number.min': '%s 不能小於 %s',
|
|
48
|
+
'uv.form.number.max': '%s 不能大於 %s',
|
|
49
|
+
'uv.form.number.range': '%s 必須在 %s 到 %s 之間',
|
|
50
|
+
'uv.form.array.len': '%s 長度必須為 %s',
|
|
51
|
+
'uv.form.array.min': '%s 長度不能小於 %s',
|
|
52
|
+
'uv.form.array.max': '%s 長度不能大於 %s',
|
|
53
|
+
'uv.form.array.range': '%s 長度必須在 %s 到 %s 之間',
|
|
54
|
+
'uv.form.pattern.mismatch': '%s 的值 %s 與格式 %s 不符',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default zhHant;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zfqh/uview-x",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "uview-x:面向 uni-app x 蒸汽模式(Vapor)、经典 uni-app Vue3 与 nvue 的 UV UI 组件库,组件保持 uv-ui API。",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"README.md",
|
|
40
40
|
"CHANGELOG.md"
|
|
41
41
|
],
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "59595760375b8c8c71d6abe4e860d4ba8ca915a1"
|
|
43
43
|
}
|