sard-uniapp 1.23.4 → 1.24.0

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -2
  3. package/components/calendar-input/calendar-input.vue +1 -0
  4. package/components/card/README.md +7 -0
  5. package/components/card/card.vue +17 -8
  6. package/components/card/common.d.ts +1 -0
  7. package/components/card/index.scss +1 -1
  8. package/components/cascader-input/cascader-input.vue +1 -0
  9. package/components/checkbox-input/checkbox-input.vue +1 -0
  10. package/components/config/index.d.ts +21 -0
  11. package/components/config/index.js +19 -1
  12. package/components/cool-icon/README.md +81 -0
  13. package/components/cool-icon/common.d.ts +21 -0
  14. package/components/cool-icon/common.js +2 -0
  15. package/components/cool-icon/cool-icon.d.ts +16 -0
  16. package/components/cool-icon/cool-icon.vue +86 -0
  17. package/components/cool-icon/index.d.ts +1 -0
  18. package/components/cool-icon/index.js +1 -0
  19. package/components/cool-icon/index.scss +186 -0
  20. package/components/cool-icon/variables.scss +12 -0
  21. package/components/datetime-picker-input/datetime-picker-input.vue +1 -0
  22. package/components/datetime-range-picker-input/datetime-range-picker-input.vue +1 -0
  23. package/components/input/common.d.ts +2 -0
  24. package/components/input/input.d.ts +1 -0
  25. package/components/input/input.vue +7 -3
  26. package/components/keyboard/README.md +15 -14
  27. package/components/keyboard/common.d.ts +3 -1
  28. package/components/keyboard/keyboard.d.ts +2 -1
  29. package/components/keyboard/keyboard.vue +9 -7
  30. package/components/radio-input/radio-input.vue +1 -0
  31. package/components/segmented/README.md +147 -0
  32. package/components/segmented/common.d.ts +52 -0
  33. package/components/segmented/common.js +8 -0
  34. package/components/segmented/index.d.ts +1 -0
  35. package/components/segmented/index.js +1 -0
  36. package/components/segmented/index.scss +60 -0
  37. package/components/segmented/segmented.d.ts +21 -0
  38. package/components/segmented/segmented.vue +163 -0
  39. package/components/segmented/variables.scss +21 -0
  40. package/components/segmented-item/common.d.ts +21 -0
  41. package/components/segmented-item/common.js +1 -0
  42. package/components/segmented-item/index.d.ts +1 -0
  43. package/components/segmented-item/index.js +1 -0
  44. package/components/segmented-item/index.scss +60 -0
  45. package/components/segmented-item/segmented-item.d.ts +14 -0
  46. package/components/segmented-item/segmented-item.vue +99 -0
  47. package/components/sticky/README.md +4 -0
  48. package/components/tree/README.md +5 -4
  49. package/components/tree/common.d.ts +5 -1
  50. package/components/tree/tree.d.ts +8 -0
  51. package/components/tree/tree.vue +11 -2
  52. package/components/tree-node/tree-node.vue +1 -1
  53. package/components/upload/README.md +15 -1
  54. package/components/upload/common.d.ts +2 -2
  55. package/components/upload/upload.d.ts +0 -1
  56. package/components/upload/upload.vue +2 -2
  57. package/components/upload/utils.d.ts +2 -2
  58. package/components/upload/utils.js +33 -2
  59. package/components/watermark/README.md +74 -0
  60. package/components/watermark/common.d.ts +37 -0
  61. package/components/watermark/common.js +10 -0
  62. package/components/watermark/index.d.ts +1 -0
  63. package/components/watermark/index.js +1 -0
  64. package/components/watermark/index.scss +28 -0
  65. package/components/watermark/variables.scss +5 -0
  66. package/components/watermark/watermark.d.ts +16 -0
  67. package/components/watermark/watermark.vue +263 -0
  68. package/global.d.ts +4 -0
  69. package/index.d.ts +4 -0
  70. package/index.js +4 -0
  71. package/index.scss +3 -0
  72. package/package.json +3 -2
  73. package/utils/array.d.ts +1 -1
  74. package/utils/geometry.d.ts +11 -0
  75. package/utils/geometry.js +28 -0
  76. package/utils/object.d.ts +2 -2
  77. package/utils/object.js +3 -3
  78. package/components/upload-preview/play.png +0 -0
@@ -0,0 +1,60 @@
1
+ @use '../style/base' as *;
2
+
3
+ @include bem(segmented) {
4
+ @include b() {
5
+ @include universal;
6
+ flex-direction: row;
7
+ align-items: stretch;
8
+ min-height: var(--sar-segmented-min-height);
9
+ padding: var(--sar-segmented-padding);
10
+ border-radius: var(--sar-segmented-border-radius);
11
+ background-color: var(--sar-segmented-bg);
12
+ font-size: var(--sar-segmented-font-size);
13
+
14
+ @include m(vertical) {
15
+ display: inline-flex;
16
+
17
+ @include e(group) {
18
+ flex-direction: column;
19
+ }
20
+
21
+ @include e(pointer) {
22
+ width: 100%;
23
+ }
24
+ }
25
+
26
+ @include m(small) {
27
+ min-height: var(--sar-segmented-small-min-height);
28
+ }
29
+
30
+ @include m(large) {
31
+ min-height: var(--sar-segmented-large-min-height);
32
+ }
33
+
34
+ @include m(round) {
35
+ border-radius: var(--sar-rounded-full);
36
+
37
+ @include e(pointer) {
38
+ border-radius: var(--sar-rounded-full);
39
+ }
40
+ }
41
+ }
42
+
43
+ @include e(pointer) {
44
+ position: absolute;
45
+ top: 0;
46
+ left: 0;
47
+ height: 100%;
48
+ border-radius: calc(var(--sar-segmented-border-radius) - 4rpx);
49
+ background-color: var(--sar-segmented-pointer-bg);
50
+ box-shadow: var(--sar-segmented-pointer-box-shadow);
51
+ transition: transform var(--sar-segmented-pointer-duration);
52
+ }
53
+
54
+ @include e(group) {
55
+ @include universal;
56
+ flex-direction: row;
57
+ align-items: stretch;
58
+ width: 100%;
59
+ }
60
+ }
@@ -0,0 +1,21 @@
1
+ import { type SegmentedProps, type SegmentedSlots } from './common';
2
+ declare function __VLS_template(): Readonly<SegmentedSlots> & SegmentedSlots;
3
+ declare const __VLS_component: import("vue").DefineComponent<SegmentedProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
+ "update:model-value": (value: any) => any;
5
+ change: (value: any) => any;
6
+ }, string, import("vue").PublicProps, Readonly<SegmentedProps> & Readonly<{
7
+ "onUpdate:model-value"?: ((value: any) => any) | undefined;
8
+ onChange?: ((value: any) => any) | undefined;
9
+ }>, {
10
+ size: import("./common").SegmentedSize;
11
+ shape: "square" | "round";
12
+ direction: "horizontal" | "vertical";
13
+ validateEvent: boolean;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
16
+ export default _default;
17
+ type __VLS_WithTemplateSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,163 @@
1
+ <template>
2
+ <view :class="segmentedClass" :style="segmentedStyle">
3
+ <view :class="groupClass">
4
+ <view :class="pointerClass" :style="pointerStyle"></view>
5
+ <slot>
6
+ <sar-segmented-item
7
+ v-for="(option, i) in convertedOptions"
8
+ :key="i"
9
+ :value="option.value"
10
+ :label="option.label"
11
+ :disabled="option.disabled"
12
+ :icon="option.icon"
13
+ :icon-family="option.iconFamily"
14
+ :icon-size="option.iconSize"
15
+ />
16
+ </slot>
17
+ </view>
18
+ </view>
19
+ </template>
20
+
21
+ <script>
22
+ import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from "vue";
23
+ import { computed, provide, reactive, ref, toRef, watch } from "vue";
24
+ import { classNames, stringifyStyle, createBem, isPrimitive } from "../../utils";
25
+ import {
26
+ defaultSegmentedProps,
27
+ defaultOptionKeys,
28
+ segmentedContextSymbol
29
+ } from "./common";
30
+ import SarSegmentedItem from "../segmented-item/segmented-item.vue";
31
+ import { useFormItemContext } from "../form";
32
+ /**
33
+ * @property {string} rootClass 组件根元素类名,默认值:-。
34
+ * @property {StyleValue} rootStyle 组件根元素样式,默认值:-。
35
+ * @property {any} modelValue 绑定值,默认值:-。
36
+ * @property {boolean} disabled 是否禁用,默认值:false。
37
+ * @property {boolean} readonly 是否只读,默认值:false。
38
+ * @property {'small' | 'middle' | 'large'} size 组件大小,默认值:'middle'。
39
+ * @property {'horizontal' | 'vertical'} direction 展示的方向,默认值:'horizontal'。
40
+ * @property {'square' | 'round'} shape 形状,默认值:'square'。
41
+ * @property {SegmentedOption[]} options 选项的数据,默认值:-。
42
+ * @property {SegmentedOptionKeys} optionKeys 自定义 options 的 label、value 的字段,默认值:{label: 'label', value: 'value'}。
43
+ * @property {boolean} validateEvent 是否触发表单验证,默认值:true。
44
+ * @event {(value: any) => void} update 当所选值更改时触发
45
+ * @event {(value: any) => void} change 当所选值更改时触发
46
+ */
47
+ export default _defineComponent({
48
+ components: {
49
+ SarSegmentedItem,
50
+ },
51
+ ...{
52
+ options: {
53
+ virtualHost: true,
54
+ styleIsolation: "shared"
55
+ }
56
+ },
57
+ __name: "segmented",
58
+ props: _mergeDefaults({
59
+ rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
60
+ rootClass: { type: String, required: false },
61
+ modelValue: { type: null, required: false },
62
+ disabled: { type: Boolean, required: false },
63
+ readonly: { type: Boolean, required: false },
64
+ size: { type: String, required: false },
65
+ direction: { type: String, required: false },
66
+ shape: { type: String, required: false },
67
+ options: { type: Array, required: false },
68
+ optionKeys: { type: Object, required: false },
69
+ validateEvent: { type: Boolean, required: false }
70
+ }, defaultSegmentedProps),
71
+ emits: ["update:model-value", "change"],
72
+ setup(__props, { expose: __expose, emit: __emit }) {
73
+ const props = __props;
74
+ const emit = __emit;
75
+ const bem = createBem("segmented");
76
+ const formItemContext = useFormItemContext();
77
+ const innerValue = ref(props.modelValue);
78
+ watch(
79
+ () => props.modelValue,
80
+ () => {
81
+ innerValue.value = props.modelValue;
82
+ if (props.validateEvent) {
83
+ formItemContext?.onChange();
84
+ }
85
+ }
86
+ );
87
+ const fieldKeys = computed(() => {
88
+ return Object.assign({}, defaultOptionKeys, props.optionKeys);
89
+ });
90
+ const convertedOptions = computed(() => {
91
+ return (props.options || []).map((option) => {
92
+ return isPrimitive(option) ? {
93
+ label: option,
94
+ value: option
95
+ } : {
96
+ label: option[fieldKeys.value.label],
97
+ value: option[fieldKeys.value.value],
98
+ disabled: option[fieldKeys.value.disabled],
99
+ icon: option.icon,
100
+ iconFamily: option.iconFamily,
101
+ iconSize: option.iconSize
102
+ };
103
+ });
104
+ });
105
+ const currentIndex = computed(() => {
106
+ return convertedOptions.value.findIndex(
107
+ (option) => option.value === innerValue.value
108
+ );
109
+ });
110
+ const optionsCount = computed(() => convertedOptions.value.length);
111
+ const toggle = (value) => {
112
+ if (value !== innerValue.value) {
113
+ innerValue.value = value;
114
+ emit("update:model-value", value);
115
+ emit("change", value);
116
+ }
117
+ };
118
+ provide(
119
+ segmentedContextSymbol,
120
+ reactive({
121
+ disabled: toRef(() => props.disabled),
122
+ readonly: toRef(() => props.readonly),
123
+ size: toRef(() => props.size),
124
+ shape: toRef(() => props.shape),
125
+ value: innerValue,
126
+ toggle
127
+ })
128
+ );
129
+ __expose({});
130
+ const segmentedClass = computed(() => {
131
+ return classNames(
132
+ bem.b(),
133
+ bem.m(props.size),
134
+ bem.m(props.direction),
135
+ bem.m(props.shape),
136
+ props.rootClass
137
+ );
138
+ });
139
+ const segmentedStyle = computed(() => {
140
+ return stringifyStyle(props.rootStyle);
141
+ });
142
+ const groupClass = computed(() => {
143
+ return classNames(bem.e("group"));
144
+ });
145
+ const pointerClass = computed(() => {
146
+ return classNames(bem.e("pointer"));
147
+ });
148
+ const pointerStyle = computed(() => {
149
+ const isHorizontal = props.direction === "horizontal";
150
+ return {
151
+ [isHorizontal ? "width" : "height"]: 1 / optionsCount.value * 100 + "%",
152
+ transform: `translate${isHorizontal ? "X" : "Y"}(${currentIndex.value * 100}%)`
153
+ };
154
+ });
155
+ const __returned__ = { props, emit, bem, formItemContext, innerValue, fieldKeys, convertedOptions, currentIndex, optionsCount, toggle, segmentedClass, segmentedStyle, groupClass, pointerClass, pointerStyle, SarSegmentedItem };
156
+ return __returned__;
157
+ }
158
+ });
159
+ </script>
160
+
161
+ <style lang="scss">
162
+ @import './index.scss';
163
+ </style>
@@ -0,0 +1,21 @@
1
+ // #variables
2
+ page,
3
+ .sar-portal {
4
+ --sar-segmented-min-height: 64rpx;
5
+ --sar-segmented-large-min-height: 80rpx;
6
+ --sar-segmented-small-min-height: 48rpx;
7
+ --sar-segmented-padding: 2px;
8
+ --sar-segmented-font-size: var(--sar-text-base);
9
+ --sar-segmented-bg: var(--sar-secondary-bg);
10
+ --sar-segmented-border-radius: var(--sar-rounded);
11
+ --sar-segmented-pointer-bg: var(--sar-emphasis-bg);
12
+ --sar-segmented-pointer-duration: var(--sar-duration);
13
+ --sar-segmented-pointer-box-shadow: var(--sar-shadow-sm);
14
+ --sar-segmented-item-padding: 24rpx;
15
+ --sar-segmented-item-small-padding: 16rpx;
16
+ --sar-segmented-item-color: var(--sar-secondary-color);
17
+ --sar-segmented-item-active-bg: var(--sar-active-deep-bg);
18
+ --sar-segmented-item-active-color: var(--sar-emphasis-color);
19
+ --sar-segmented-item-label-margin-left: 12rpx;
20
+ }
21
+ // #endvariables
@@ -0,0 +1,21 @@
1
+ import { type StyleValue } from 'vue';
2
+ export interface SegmentedItemProps {
3
+ rootStyle?: StyleValue;
4
+ rootClass?: string;
5
+ label?: string | number;
6
+ value?: string | number | boolean;
7
+ icon?: string;
8
+ iconFamily?: string;
9
+ iconSize?: string;
10
+ disabled?: boolean;
11
+ readonly?: boolean;
12
+ }
13
+ export declare const defaultSegmentedItemProps: {};
14
+ export interface SegmentedItemSlots {
15
+ default?(props: Record<string, never>): any;
16
+ }
17
+ export interface SegmentedItemEmits {
18
+ (e: 'click', event: any): void;
19
+ }
20
+ export interface SegmentedItemExpose {
21
+ }
@@ -0,0 +1 @@
1
+ export const defaultSegmentedItemProps = {};
@@ -0,0 +1 @@
1
+ export type { SegmentedItemProps, SegmentedItemSlots, SegmentedItemEmits, SegmentedItemExpose, } from './common';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ @use '../style/base' as *;
2
+
3
+ @include bem(segmented-item) {
4
+ @include b() {
5
+ @include universal;
6
+ flex-direction: row;
7
+ flex: 1;
8
+ justify-content: center;
9
+ align-items: center;
10
+ min-width: 0;
11
+ min-height: calc(
12
+ var(--sar-segmented-min-height) - var(--sar-segmented-padding) * 2
13
+ );
14
+ padding: 0 var(--sar-segmented-item-padding);
15
+ border-radius: calc(var(--sar-segmented-border-radius) - 4rpx);
16
+ color: var(--sar-segmented-item-color);
17
+
18
+ @include m(small) {
19
+ min-height: calc(
20
+ var(--sar-segmented-small-min-height) - var(--sar-segmented-padding) * 2
21
+ );
22
+ }
23
+
24
+ @include m(large) {
25
+ min-height: calc(
26
+ var(--sar-segmented-large-min-height) - var(--sar-segmented-padding) * 2
27
+ );
28
+ }
29
+
30
+ @include m(round) {
31
+ border-radius: var(--sar-rounded-full);
32
+ }
33
+
34
+ @include m(with-icon) {
35
+ @include e(label) {
36
+ margin-left: var(--sar-segmented-item-label-margin-left);
37
+ }
38
+ }
39
+
40
+ @include m-not(disabled, readonly, selected) {
41
+ cursor: pointer;
42
+
43
+ &:active {
44
+ background-color: var(--sar-segmented-item-active-bg);
45
+ }
46
+ }
47
+
48
+ @include m(selected) {
49
+ color: var(--sar-segmented-item-active-color);
50
+ }
51
+
52
+ @include m(disabled) {
53
+ @include disabled-text;
54
+ }
55
+ }
56
+
57
+ @include e(label) {
58
+ @include ellipsis;
59
+ }
60
+ }
@@ -0,0 +1,14 @@
1
+ import { type SegmentedItemProps, type SegmentedItemSlots } from './common';
2
+ declare function __VLS_template(): Readonly<SegmentedItemSlots> & SegmentedItemSlots;
3
+ declare const __VLS_component: import("vue").DefineComponent<SegmentedItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
+ click: (event: any) => any;
5
+ }, string, import("vue").PublicProps, Readonly<SegmentedItemProps> & Readonly<{
6
+ onClick?: ((event: any) => any) | undefined;
7
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
9
+ export default _default;
10
+ type __VLS_WithTemplateSlots<T, S> = T & {
11
+ new (): {
12
+ $slots: S;
13
+ };
14
+ };
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <view
3
+ :class="segmentedItemClass"
4
+ :style="segmentedItemStyle"
5
+ @click="onClick"
6
+ >
7
+ <slot>
8
+ <view :class="bem.e('icon')">
9
+ <sar-icon :name="icon" :family="iconFamily" :size="iconSize" />
10
+ </view>
11
+ <view v-if="label" :class="bem.e('label')">{{ label }}</view>
12
+ </slot>
13
+ </view>
14
+ </template>
15
+
16
+ <script>
17
+ import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from "vue";
18
+ import { computed, inject } from "vue";
19
+ import { classNames, stringifyStyle, createBem } from "../../utils";
20
+ import {
21
+ defaultSegmentedItemProps
22
+ } from "./common";
23
+ import {
24
+ segmentedContextSymbol
25
+ } from "../segmented/common";
26
+ import SarIcon from "../icon/icon.vue";
27
+ import { useFormContext } from "../form";
28
+ export default _defineComponent({
29
+ components: {
30
+ SarIcon,
31
+ },
32
+ ...{
33
+ options: {
34
+ virtualHost: true,
35
+ styleIsolation: "shared"
36
+ }
37
+ },
38
+ __name: "segmented-item",
39
+ props: _mergeDefaults({
40
+ rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
41
+ rootClass: { type: String, required: false },
42
+ label: { type: [String, Number], required: false },
43
+ value: { type: [String, Number, Boolean], required: false },
44
+ icon: { type: String, required: false },
45
+ iconFamily: { type: String, required: false },
46
+ iconSize: { type: String, required: false },
47
+ disabled: { type: Boolean, required: false },
48
+ readonly: { type: Boolean, required: false }
49
+ }, defaultSegmentedItemProps),
50
+ emits: ["click"],
51
+ setup(__props, { expose: __expose, emit: __emit }) {
52
+ const props = __props;
53
+ const emit = __emit;
54
+ const bem = createBem("segmented-item");
55
+ const context = inject(segmentedContextSymbol, null);
56
+ if (!context) {
57
+ throw new Error("SegmentedItem must be included in Segmented.");
58
+ }
59
+ const formContext = useFormContext();
60
+ const isSelected = computed(() => {
61
+ return context.value === props.value;
62
+ });
63
+ const isDisabled = computed(() => {
64
+ return formContext?.disabled || context?.disabled || props.disabled;
65
+ });
66
+ const isReadonly = computed(() => {
67
+ return formContext?.readonly || context?.readonly || props.readonly;
68
+ });
69
+ const onClick = (event) => {
70
+ if (!isDisabled.value && !isReadonly.value) {
71
+ context.toggle(props.value);
72
+ }
73
+ emit("click", event);
74
+ };
75
+ __expose({});
76
+ const segmentedItemClass = computed(() => {
77
+ return classNames(
78
+ bem.b(),
79
+ bem.m("selected", isSelected.value),
80
+ bem.m("disabled", isDisabled.value),
81
+ bem.m("readonly", isReadonly.value),
82
+ bem.m("with-icon", !!props.icon),
83
+ bem.m(context.size),
84
+ bem.m(context.shape),
85
+ props.rootClass
86
+ );
87
+ });
88
+ const segmentedItemStyle = computed(() => {
89
+ return stringifyStyle(props.rootStyle);
90
+ });
91
+ const __returned__ = { props, emit, bem, context, formContext, isSelected, isDisabled, isReadonly, onClick, segmentedItemClass, segmentedItemStyle, SarIcon };
92
+ return __returned__;
93
+ }
94
+ });
95
+ </script>
96
+
97
+ <style lang="scss">
98
+ @import './index.scss';
99
+ </style>
@@ -39,6 +39,10 @@ import StickyBox from 'sard-uniapp/components/sticky-box/sticky-box.vue'
39
39
 
40
40
  @code('${DEMO_PATH}/sticky/demo/OffsetTop.vue')
41
41
 
42
+ `@/utils`
43
+
44
+ @code('${ROOT_PATH}/utils/index.ts')
45
+
42
46
  ### 动态插入
43
47
 
44
48
  即使是动态插入的数据,`Sticky` 组件也能重新计算其位置。
@@ -121,10 +121,11 @@ import Tree from 'sard-uniapp/components/tree/tree.vue'
121
121
 
122
122
  ### TreeEmits
123
123
 
124
- | 事件 | 描述 | 类型 |
125
- | ------------------------------- | ---------------------- | ---------------------------------------------------- |
126
- | update:current <sup>1.17+</sup> | 选择节点后触发(单选) | (key: string \| number, node: TreeStateNode) => void |
127
- | select <sup>1.17+</sup> | 选择节点后触发(单选) | (key: string \| number, node: TreeStateNode) => void |
124
+ | 事件 | 描述 | 类型 |
125
+ | ------------------------------- | ---------------------- | -------------------------------------------------------- |
126
+ | update:current <sup>1.17+</sup> | 选择节点后触发(单选) | (key: string \| number, node: TreeStateNode) => void |
127
+ | select <sup>1.17+</sup> | 选择节点后触发(单选) | (key: string \| number, node: TreeStateNode) => void |
128
+ | check <sup>1.24+</sup> | 点击树节点复选框时触发 | (event: {checked: boolean; node: TreeStateNode}) => void |
128
129
 
129
130
  ### TreeExpose
130
131
 
@@ -63,6 +63,10 @@ export declare const defaultTreeProps: () => {
63
63
  export interface TreeEmits {
64
64
  (e: 'update:current', key: string | number, node: TreeStateNode): void;
65
65
  (e: 'select', key: string | number, node: TreeStateNode): void;
66
+ (e: 'check', event: {
67
+ checked: boolean;
68
+ node: TreeStateNode;
69
+ }): void;
66
70
  }
67
71
  export interface TreeExpose {
68
72
  setExpanded: (key: string | number, expanded: boolean) => void;
@@ -93,7 +97,7 @@ export interface TreeContext {
93
97
  treeData: TreeStateNode[];
94
98
  setExpandedByNode: (node: TreeStateNode, expanded: boolean) => void;
95
99
  toggleExpandedByNode: (node: TreeStateNode) => void;
96
- setCheckedByNode: (node: TreeStateNode, checked: boolean) => void;
100
+ toggleCheck: (node: TreeStateNode, checked: boolean) => void;
97
101
  levelup: (node: TreeStateNode) => void;
98
102
  leveldown: (node: TreeStateNode) => void;
99
103
  edit: (node: TreeStateNode, getEditRect: () => Promise<NodeRect>) => void;
@@ -14,9 +14,17 @@ declare const _default: import("vue").DefineComponent<TreeProps, {
14
14
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
15
15
  select: (key: string | number, node: TreeStateNode) => any;
16
16
  "update:current": (key: string | number, node: TreeStateNode) => any;
17
+ check: (event: {
18
+ checked: boolean;
19
+ node: TreeStateNode;
20
+ }) => any;
17
21
  }, string, import("vue").PublicProps, Readonly<TreeProps> & Readonly<{
18
22
  onSelect?: ((key: string | number, node: TreeStateNode) => any) | undefined;
19
23
  "onUpdate:current"?: ((key: string | number, node: TreeStateNode) => any) | undefined;
24
+ onCheck?: ((event: {
25
+ checked: boolean;
26
+ node: TreeStateNode;
27
+ }) => any) | undefined;
20
28
  }>, {
21
29
  data: TreeNode[];
22
30
  accordion: boolean;
@@ -75,6 +75,7 @@ import { recurAncestor, recurDescendant, recurNodes } from "./utils";
75
75
  * @property {(value: string, node: TreeStateNode) => boolean} filterMethod 自定义过滤方法,默认值:-。
76
76
  * @event {(key: string | number, node: TreeStateNode) => void} update 选择节点后触发(单选)
77
77
  * @event {(key: string | number, node: TreeStateNode) => void} select 选择节点后触发(单选)
78
+ * @event {(event: {checked: boolean; node: TreeStateNode}) => void} check 点击树节点复选框时触发
78
79
  */
79
80
  export default _defineComponent({
80
81
  components: {
@@ -110,7 +111,7 @@ export default _defineComponent({
110
111
  filterMode: { type: String, required: false },
111
112
  filterMethod: { type: Function, required: false }
112
113
  }, defaultTreeProps()),
113
- emits: ["update:current", "select"],
114
+ emits: ["update:current", "select", "check"],
114
115
  setup(__props, { expose: __expose, emit: __emit }) {
115
116
  const props = __props;
116
117
  const emit = __emit;
@@ -399,6 +400,13 @@ export default _defineComponent({
399
400
  recur(treeData.value);
400
401
  totalLevel.value = count;
401
402
  };
403
+ const toggleCheck = (node, checked) => {
404
+ setCheckedByNode(node, checked);
405
+ emit("check", {
406
+ checked,
407
+ node
408
+ });
409
+ };
402
410
  watch(
403
411
  () => props.data,
404
412
  () => {
@@ -559,6 +567,7 @@ export default _defineComponent({
559
567
  levelup,
560
568
  leveldown,
561
569
  drop,
570
+ toggleCheck,
562
571
  edit,
563
572
  currentKey,
564
573
  singleSelect
@@ -592,7 +601,7 @@ export default _defineComponent({
592
601
  return treeMap;
593
602
  }, set treeMap(v) {
594
603
  treeMap = v;
595
- }, totalLevel, recurRawNode, setExpandedByNode, toggleExpandedByNode, setExpanded, toggleExpanded, setExpandedKeys, getExpandedKeys, setCheckedByNode, updateAncestorChecked, setCheckedKeys, setChecked, getCheckedKeys, getHalfCheckedKeys, prepend, append, appendRoot, before, after, remove, levelup, leveldown, drop, addRootNode, getCleanTreeData, setRenderPosition, popoverOptions, popover, get currentEditNode() {
604
+ }, totalLevel, recurRawNode, setExpandedByNode, toggleExpandedByNode, setExpanded, toggleExpanded, setExpandedKeys, getExpandedKeys, setCheckedByNode, updateAncestorChecked, setCheckedKeys, setChecked, getCheckedKeys, getHalfCheckedKeys, prepend, append, appendRoot, before, after, remove, levelup, leveldown, drop, addRootNode, getCleanTreeData, setRenderPosition, toggleCheck, popoverOptions, popover, get currentEditNode() {
596
605
  return currentEditNode;
597
606
  }, set currentEditNode(v) {
598
607
  currentEditNode = v;
@@ -299,7 +299,7 @@ export default _defineComponent({
299
299
  const [onSelectionTouchStart, onSelectionTouchEnd] = useSimulatedClick(() => {
300
300
  if (!props.node.disabled) {
301
301
  if (treeContext.selectable) {
302
- treeContext.setCheckedByNode(props.node, !props.node.checked);
302
+ treeContext.toggleCheck(props.node, !props.node.checked);
303
303
  }
304
304
  if (canSingleSelectable.value) {
305
305
  treeContext.singleSelect(props.node);
@@ -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' | 'image' |
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;