sard-uniapp 1.23.4 → 1.23.5
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 +10 -0
- package/components/config/index.d.ts +1 -0
- package/components/config/index.js +1 -0
- package/components/input/common.d.ts +2 -0
- package/components/input/input.d.ts +1 -0
- package/components/input/input.vue +7 -3
- package/components/upload/README.md +15 -1
- package/components/upload/common.d.ts +2 -2
- package/components/upload/upload.d.ts +0 -1
- package/components/upload/upload.vue +2 -2
- package/components/upload/utils.d.ts +2 -2
- package/components/upload/utils.js +33 -2
- package/package.json +1 -1
- package/utils/array.d.ts +1 -1
- package/utils/object.d.ts +2 -2
- package/utils/object.js +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [1.23.5](https://github.com/sutras/sard-uniapp/compare/v1.23.4...v1.23.5) (2025-08-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **input:** 添加 enableNative 属性以支持支付宝小程序 ([5c8b616](https://github.com/sutras/sard-uniapp/commit/5c8b61624b35a543e87d030266f706eeda819447))
|
|
7
|
+
* **update:** 允许同时选择图片和视频 ([d478208](https://github.com/sutras/sard-uniapp/commit/d4782089767950340448c87bd1bccb43759ede77))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
1
11
|
## [1.23.4](https://github.com/sutras/sard-uniapp/compare/v1.23.3...v1.23.4) (2025-08-11)
|
|
2
12
|
|
|
3
13
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type StyleValue } from 'vue';
|
|
2
2
|
export interface InputProps {
|
|
3
|
+
enableNative?: boolean;
|
|
3
4
|
placeholder?: string;
|
|
4
5
|
placeholderStyle?: string;
|
|
5
6
|
placeholderClass?: string;
|
|
@@ -49,6 +50,7 @@ export interface InputProps {
|
|
|
49
50
|
internalPrepend?: number;
|
|
50
51
|
}
|
|
51
52
|
export declare const defaultInputProps: {
|
|
53
|
+
enableNative: boolean;
|
|
52
54
|
maxlength: number;
|
|
53
55
|
adjustPosition: boolean;
|
|
54
56
|
ignoreCompositionEvent: boolean;
|
|
@@ -11,6 +11,7 @@ declare const __VLS_component: import("vue").DefineComponent<InputProps, {}, {},
|
|
|
11
11
|
confirmType: "send" | "search" | "next" | "go" | "done";
|
|
12
12
|
inputmode: "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
|
|
13
13
|
validateEvent: boolean;
|
|
14
|
+
enableNative: boolean;
|
|
14
15
|
maxlength: number;
|
|
15
16
|
cursorSpacing: number;
|
|
16
17
|
cursor: number;
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
bem.em('control', 'input-min-height', inputMinHeight),
|
|
17
17
|
)
|
|
18
18
|
"
|
|
19
|
+
:enableNative="enableNative"
|
|
20
|
+
:value="innerValue"
|
|
19
21
|
:placeholder="placeholder"
|
|
20
22
|
:placeholder-style="mergedPlaceholderStyle"
|
|
21
23
|
:placeholder-class="placeholderClass"
|
|
22
|
-
:value="innerValue"
|
|
23
24
|
:disabled="isDisabled || isReadonly"
|
|
24
25
|
:maxlength="maxlength"
|
|
25
26
|
:focus="focus"
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
<input
|
|
52
53
|
v-if="type !== 'textarea' && showPassword"
|
|
53
54
|
:class="classNames(bem.e('control'), bem.em('control', 'input'))"
|
|
55
|
+
:enableNative="enableNative"
|
|
54
56
|
:value="innerValue"
|
|
55
57
|
:placeholder="placeholder"
|
|
56
58
|
:placeholder-style="mergedPlaceholderStyle"
|
|
@@ -91,6 +93,7 @@
|
|
|
91
93
|
<input
|
|
92
94
|
v-if="type !== 'textarea' && !showPassword"
|
|
93
95
|
:class="classNames(bem.e('control'), bem.em('control', 'input'))"
|
|
96
|
+
:enableNative="enableNative"
|
|
94
97
|
:value="innerValue"
|
|
95
98
|
:placeholder="placeholder"
|
|
96
99
|
:placeholder-style="mergedPlaceholderStyle"
|
|
@@ -236,6 +239,7 @@ export default _defineComponent({
|
|
|
236
239
|
},
|
|
237
240
|
__name: "input",
|
|
238
241
|
props: _mergeDefaults({
|
|
242
|
+
enableNative: { type: Boolean, required: false },
|
|
239
243
|
placeholder: { type: String, required: false },
|
|
240
244
|
placeholderStyle: { type: String, required: false },
|
|
241
245
|
placeholderClass: { type: String, required: false },
|
|
@@ -386,10 +390,10 @@ export default _defineComponent({
|
|
|
386
390
|
const showPassword = computed(() => {
|
|
387
391
|
return props.type === "password" && isPlainText.value === false;
|
|
388
392
|
});
|
|
389
|
-
const mergedShowEye = computed(() => props.type === "password" && props.showEye);
|
|
390
393
|
const mergedType = computed(() => {
|
|
391
394
|
return showPassword.value ? "password" : props.type === "password" ? "text" : props.type;
|
|
392
395
|
});
|
|
396
|
+
const mergedShowEye = computed(() => props.type === "password" && props.showEye);
|
|
393
397
|
const inputClass = computed(() => {
|
|
394
398
|
return classNames(
|
|
395
399
|
bem.b(),
|
|
@@ -428,7 +432,7 @@ export default _defineComponent({
|
|
|
428
432
|
return oldValue;
|
|
429
433
|
}, set oldValue(v) {
|
|
430
434
|
oldValue = v;
|
|
431
|
-
}, onFocus, onBlur, clearVisible, holdupClear, onClearTouchStart, onClearTouchEnd, onClearMouseDown, onClearClick, onLinechange, onConfirm, onKeyboardheightchange, onClick, isPlainText, eyeIcon, onEyeClick, showPassword,
|
|
435
|
+
}, onFocus, onBlur, clearVisible, holdupClear, onClearTouchStart, onClearTouchEnd, onClearMouseDown, onClearClick, onLinechange, onConfirm, onKeyboardheightchange, onClick, isPlainText, eyeIcon, onEyeClick, showPassword, mergedType, mergedShowEye, inputClass, inputStyle, controlStyle, mergedPlaceholderStyle, get classNames() {
|
|
432
436
|
return classNames;
|
|
433
437
|
}, SarIcon };
|
|
434
438
|
return __returned__;
|
|
@@ -29,6 +29,20 @@ import Upload from 'sard-uniapp/components/upload/upload.vue'
|
|
|
29
29
|
|
|
30
30
|
@code('${DEMO_PATH}/upload/demo/Video.vue')
|
|
31
31
|
|
|
32
|
+
### 同时上传图片和视频 <sup>1.23.5+</sup>
|
|
33
|
+
|
|
34
|
+
@info
|
|
35
|
+
|
|
36
|
+
仅 app 和微信支持。
|
|
37
|
+
|
|
38
|
+
不支持的端,默认回退为选择图片。
|
|
39
|
+
|
|
40
|
+
@endinfo
|
|
41
|
+
|
|
42
|
+
设置 `:accept="['image', 'video']"` 允许同时选择图片和视频。
|
|
43
|
+
|
|
44
|
+
@code('${DEMO_PATH}/upload/demo/Mix.vue')
|
|
45
|
+
|
|
32
46
|
### 限定上传数量
|
|
33
47
|
|
|
34
48
|
通过 `maxCount` 属性可以限制上传文件的数量,上传数量达到限制后,会自动隐藏选择区域。
|
|
@@ -99,7 +113,7 @@ import Upload from 'sard-uniapp/components/upload/upload.vue'
|
|
|
99
113
|
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------- |
|
|
100
114
|
| root-class | 组件根元素类名 | string | - |
|
|
101
115
|
| root-style | 组件根元素样式 | StyleValue | - |
|
|
102
|
-
| accept | 允许上传的文件类型 | 'image' \| 'video'
|
|
116
|
+
| accept | 允许上传的文件类型 | 'image' \| 'video' \| ('image' \| 'video' )[] | 'image' |
|
|
103
117
|
| multiple | 是否开启图片多选 | boolean | false |
|
|
104
118
|
| source-type | 文件选择来源 | ('album' \| 'camera')[] | ['album', 'camera'] |
|
|
105
119
|
| size-type | 所选的图片的尺寸 | ('original' \| 'compressed')[] | ['original', 'compressed'] |
|
|
@@ -26,7 +26,7 @@ export interface UploadSelectOptions {
|
|
|
26
26
|
export interface UploadProps {
|
|
27
27
|
rootStyle?: StyleValue;
|
|
28
28
|
rootClass?: string;
|
|
29
|
-
accept?: 'image' | 'video';
|
|
29
|
+
accept?: 'image' | 'video' | ('image' | 'video')[];
|
|
30
30
|
multiple?: boolean;
|
|
31
31
|
sourceType?: ('album' | 'camera')[];
|
|
32
32
|
sizeType?: ('original' | 'compressed')[];
|
|
@@ -45,7 +45,7 @@ export interface UploadProps {
|
|
|
45
45
|
beforeRemove?: (index: number, fileItem: UploadFileItem) => boolean | Promise<void>;
|
|
46
46
|
validateEvent?: boolean;
|
|
47
47
|
}
|
|
48
|
-
export declare const defaultUploadProps: Omit<typeof defaultConfig.upload, "sourceType" | "sizeType">;
|
|
48
|
+
export declare const defaultUploadProps: Omit<typeof defaultConfig.upload, "sourceType" | "sizeType" | "accept">;
|
|
49
49
|
export interface UploadSlots {
|
|
50
50
|
default?(props: {
|
|
51
51
|
list: UploadFileItem[];
|
|
@@ -11,7 +11,6 @@ declare const __VLS_component: import("vue").DefineComponent<UploadProps, {}, {}
|
|
|
11
11
|
onRemove?: ((index: number, item: UploadFileItem) => any) | undefined;
|
|
12
12
|
"onItem-click"?: ((item: UploadFileItem, index: number) => any) | undefined;
|
|
13
13
|
}>, {
|
|
14
|
-
accept: "image" | "video";
|
|
15
14
|
validateEvent: boolean;
|
|
16
15
|
maxDuration: number;
|
|
17
16
|
maxCount: number;
|
|
@@ -64,7 +64,7 @@ import { useFormContext, useFormItemContext } from "../form/common";
|
|
|
64
64
|
/**
|
|
65
65
|
* @property {string} rootClass 组件根元素类名,默认值:-。
|
|
66
66
|
* @property {StyleValue} rootStyle 组件根元素样式,默认值:-。
|
|
67
|
-
* @property {'image' | 'video'} accept 允许上传的文件类型,默认值:'image'。
|
|
67
|
+
* @property {'image' | 'video' | ('image' | 'video' )[]} accept 允许上传的文件类型,默认值:'image'。
|
|
68
68
|
* @property {boolean} multiple 是否开启图片多选,默认值:false。
|
|
69
69
|
* @property {('album' | 'camera')[]} sourceType 文件选择来源,默认值:['album', 'camera']。
|
|
70
70
|
* @property {('original' | 'compressed')[]} sizeType 所选的图片的尺寸,默认值:['original', 'compressed']。
|
|
@@ -102,7 +102,7 @@ export default _defineComponent({
|
|
|
102
102
|
props: _mergeDefaults({
|
|
103
103
|
rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
|
|
104
104
|
rootClass: { type: String, required: false },
|
|
105
|
-
accept: { type: String, required: false },
|
|
105
|
+
accept: { type: [String, Array], required: false },
|
|
106
106
|
multiple: { type: Boolean, required: false },
|
|
107
107
|
sourceType: { type: Array, required: false },
|
|
108
108
|
sizeType: { type: Array, required: false },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
interface chooseMediaOptions {
|
|
2
2
|
count?: number;
|
|
3
|
-
mediaType?: 'image' | 'video';
|
|
3
|
+
mediaType?: 'image' | 'video' | ('image' | 'video')[];
|
|
4
4
|
sourceType?: ('album' | 'camera')[];
|
|
5
5
|
maxDuration?: number;
|
|
6
6
|
sizeType?: ('original' | 'compressed')[];
|
|
@@ -19,7 +19,7 @@ interface chooseMediaResult {
|
|
|
19
19
|
fileType: 'image' | 'video';
|
|
20
20
|
name: string;
|
|
21
21
|
}[];
|
|
22
|
-
type: 'image' | 'video';
|
|
22
|
+
type: 'image' | 'video' | 'mix';
|
|
23
23
|
}
|
|
24
24
|
export declare function chooseMedia(options: chooseMediaOptions): void;
|
|
25
25
|
export {};
|
|
@@ -1,7 +1,38 @@
|
|
|
1
1
|
import { toArray } from '../../utils';
|
|
2
2
|
export function chooseMedia(options) {
|
|
3
3
|
const { count = 9, mediaType = 'image', sourceType = ['album', 'camera'], maxDuration = 10, sizeType = ['original', 'compressed'], camera = 'back', success, fail, complete, } = options;
|
|
4
|
-
|
|
4
|
+
const arrayMediaType = toArray(mediaType);
|
|
5
|
+
const hasImage = arrayMediaType.includes('image');
|
|
6
|
+
const hasVideo = arrayMediaType.includes('video');
|
|
7
|
+
if (hasImage && hasVideo && uni.chooseMedia) {
|
|
8
|
+
return uni.chooseMedia({
|
|
9
|
+
count,
|
|
10
|
+
mediaType: ['image', 'video'],
|
|
11
|
+
sourceType,
|
|
12
|
+
maxDuration,
|
|
13
|
+
sizeType,
|
|
14
|
+
camera,
|
|
15
|
+
success(res) {
|
|
16
|
+
success?.({
|
|
17
|
+
type: res.type,
|
|
18
|
+
tempFiles: toArray(res.tempFiles).map((file) => {
|
|
19
|
+
return {
|
|
20
|
+
tempFilePath: file.tempFilePath,
|
|
21
|
+
size: file.size,
|
|
22
|
+
duration: file.duration,
|
|
23
|
+
height: file.height,
|
|
24
|
+
width: file.width,
|
|
25
|
+
name: '',
|
|
26
|
+
fileType: file.fileType,
|
|
27
|
+
};
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
fail,
|
|
32
|
+
complete,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else if (hasImage) {
|
|
5
36
|
return uni.chooseImage({
|
|
6
37
|
count,
|
|
7
38
|
sizeType,
|
|
@@ -26,7 +57,7 @@ export function chooseMedia(options) {
|
|
|
26
57
|
complete,
|
|
27
58
|
});
|
|
28
59
|
}
|
|
29
|
-
else {
|
|
60
|
+
else if (hasVideo) {
|
|
30
61
|
return uni.chooseVideo({
|
|
31
62
|
sourceType,
|
|
32
63
|
compressed: sizeType.includes('compressed'),
|
package/package.json
CHANGED
package/utils/array.d.ts
CHANGED
package/utils/object.d.ts
CHANGED
|
@@ -19,14 +19,14 @@ export declare function treeToMap(tree: AnyObject[], keyName: string, childrenNa
|
|
|
19
19
|
* @param object
|
|
20
20
|
* @param chain 通过点分割的字符串或者字符串数组
|
|
21
21
|
*/
|
|
22
|
-
export declare function chainGet(object: any, chain?: string | string[]): any;
|
|
22
|
+
export declare function chainGet(object: any, chain?: string | number | (string | number)[]): any;
|
|
23
23
|
/**
|
|
24
24
|
* @description: 链式设置对象值
|
|
25
25
|
* @param object
|
|
26
26
|
* @param chain 通过点分割的字符串或者字符串数组
|
|
27
27
|
* @param value 要设置的值
|
|
28
28
|
*/
|
|
29
|
-
export declare function chainSet(object: any, chain: string | string[], value: any): void;
|
|
29
|
+
export declare function chainSet(object: any, chain: string | number | (string | number)[], value: any): void;
|
|
30
30
|
export declare function nestedToMulti(nested: any[], values: (number | string)[], fieldKeys: {
|
|
31
31
|
value: string;
|
|
32
32
|
children: string;
|
package/utils/object.js
CHANGED
|
@@ -89,8 +89,8 @@ export function treeToMap(tree, keyName, childrenName, parentName) {
|
|
|
89
89
|
*/
|
|
90
90
|
export function chainGet(object, chain) {
|
|
91
91
|
let target = object;
|
|
92
|
-
if (chain) {
|
|
93
|
-
chain =
|
|
92
|
+
if (chain || chain === 0) {
|
|
93
|
+
chain = Array.isArray(chain) ? chain : String(chain).split('.');
|
|
94
94
|
for (const key of chain) {
|
|
95
95
|
if (target && typeof target === 'object') {
|
|
96
96
|
target = target[key];
|
|
@@ -110,7 +110,7 @@ export function chainGet(object, chain) {
|
|
|
110
110
|
*/
|
|
111
111
|
export function chainSet(object, chain, value) {
|
|
112
112
|
let target = object;
|
|
113
|
-
chain =
|
|
113
|
+
chain = Array.isArray(chain) ? chain : String(chain).split('.');
|
|
114
114
|
if (chain.length === 0) {
|
|
115
115
|
return;
|
|
116
116
|
}
|