sard-uniapp 1.24.3 → 1.24.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 CHANGED
@@ -1,3 +1,28 @@
1
+ ## [1.24.5](https://github.com/sutras/sard-uniapp/compare/v1.24.4...v1.24.5) (2025-09-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **popout:** 修复popout类组件不显示按钮的问题 ([47bcea9](https://github.com/sutras/sard-uniapp/commit/47bcea986609b927a79d2bd917f907eda1757f82))
7
+ * **utils:** 修复 支付宝getWindowInfo没有safeAreaInsets属性的问题 ([3d64401](https://github.com/sutras/sard-uniapp/commit/3d64401aa9f71d468e9463160493c981a3caa323))
8
+ * 修复倒计时小时溢出的问题 ([823faa1](https://github.com/sutras/sard-uniapp/commit/823faa107517f91b1b630d70986a3e8b1206c39e))
9
+
10
+
11
+ ### Features
12
+
13
+ * 新增 avatar-group 组件 ([4954219](https://github.com/sutras/sard-uniapp/commit/4954219095bc3cff12d7de74c90af188b54a99fc))
14
+
15
+
16
+
17
+ ## [1.24.4](https://github.com/sutras/sard-uniapp/compare/v1.24.3...v1.24.4) (2025-09-13)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **form-item:** 修复滚动报错问题 ([046fc16](https://github.com/sutras/sard-uniapp/commit/046fc16abc03e260172eb9a6f763b241d58ebd05))
23
+
24
+
25
+
1
26
  ## [1.24.3](https://github.com/sutras/sard-uniapp/compare/v1.24.2...v1.24.3) (2025-09-13)
2
27
 
3
28
 
@@ -13,6 +13,7 @@ group: 数据展示
13
13
 
14
14
  ```ts
15
15
  import Avatar from 'sard-uniapp/components/avatar/avatar.vue'
16
+ import AvatarGroup from 'sard-uniapp/components/avatar-group/avatar-group.vue'
16
17
  ```
17
18
 
18
19
  ## 代码演示
@@ -59,18 +60,39 @@ import Avatar from 'sard-uniapp/components/avatar/avatar.vue'
59
60
 
60
61
  @code('${DEMO_PATH}/avatar/demo/Extra.vue')
61
62
 
63
+ ### 头像组 <sup>1.24.5+</sup>
64
+
65
+ 把一组 `Avatar` 组件放置在 `AvatarGroup` 组件里面,可形成层叠效果的头像组。
66
+
67
+ `AvatarGroup` 组件需传递 `total` 和 `max` 属性,以便计算省略的头像数。
68
+
69
+ @code('${DEMO_PATH}/avatar/demo/Group.vue')
70
+
71
+ ### 实际头像数不超过最大数 <sup>1.24.5+</sup>
72
+
73
+ 实际头像数不超过最大数时,会隐藏剩余数量显示。
74
+
75
+ @code('${DEMO_PATH}/avatar/demo/GroupLess.vue')
76
+
77
+ ### 覆盖面 <sup>1.24.5+</sup>
78
+
79
+ 使用 `coverage` 属性设置头像间的覆盖面,设置0时不覆盖,设置1时完全覆盖。
80
+
81
+ @code('${DEMO_PATH}/avatar/demo/GroupCoverage.vue')
82
+
62
83
  ## API
63
84
 
64
85
  ### AvatarProps
65
86
 
66
- | 属性 | 描述 | 类型 | 默认值 |
67
- | ---------- | ---------------------- | -------------------- | -------- |
68
- | root-class | 组件根元素类名 | string | - |
69
- | root-style | 组件根元素样式 | StyleValue | - |
70
- | shape | 头像形状 | 'circle' \| 'square' | 'circle' |
71
- | size | 头像尺寸 | string | - |
72
- | icon-size | 图标尺寸 | string | - |
73
- | src | 图片类型头像的图片地址 | string | - |
87
+ | 属性 | 描述 | 类型 | 默认值 |
88
+ | ------------------------ | -------------------------------------------- | -------------------- | -------- |
89
+ | root-class | 组件根元素类名 | string | - |
90
+ | root-style | 组件根元素样式 | StyleValue | - |
91
+ | shape | 头像形状 | 'circle' \| 'square' | 'circle' |
92
+ | size | 头像尺寸 | string | - |
93
+ | icon-size | 图标尺寸 | string | - |
94
+ | src | 图片类型头像的图片地址 | string | - |
95
+ | index <sup>1.24.5+</sup> | 位于头像组中时必传,当前头像在头像组中的下标 | number | - |
74
96
 
75
97
  ### AvatarSlots
76
98
 
@@ -79,6 +101,36 @@ import Avatar from 'sard-uniapp/components/avatar/avatar.vue'
79
101
  | default | 自定义默认内容 | - |
80
102
  | extra | 额外内容,常用于展示徽标 | - |
81
103
 
104
+ ### AvatarEmits
105
+
106
+ | 事件 | 描述 | 类型 |
107
+ | ------------------------ | ---------- | -------------------- |
108
+ | click <sup>1.24.5+</sup> | 点击时触发 | (event: any) => void |
109
+
110
+ ### AvatarGroupProps <sup>1.24.5+</sup>
111
+
112
+ | 属性 | 描述 | 类型 | 默认值 |
113
+ | ----------- | ------------------------ | ----------------- | ------ |
114
+ | root-class | 组件根元素类名 | string | - |
115
+ | root-style | 组件根元素样式 | StyleValue | - |
116
+ | max | 最大头像展示数量,必填 | number | - |
117
+ | total | 总的头像个数,必填 | number | - |
118
+ | coverage | 头像间的覆盖面 | number | 0.5 |
119
+ | show-remain | 是否显示剩余头像数量 | boolean | true |
120
+ | remain-text | 自定义剩余头像数量的内容 | string \| boolean | - |
121
+
122
+ ### AvatarGroupSlots <sup>1.24.5+</sup>
123
+
124
+ | 插槽 | 描述 | 属性 |
125
+ | ------- | -------------- | ---- |
126
+ | default | 自定义默认内容 | - |
127
+
128
+ ### AvatarGroupEmits <sup>1.24.5+</sup>
129
+
130
+ | 事件 | 描述 | 类型 |
131
+ | ------------------------------- | ------------------ | -------------------- |
132
+ | remain-click <sup>1.24.5+</sup> | 点击剩余数量时触发 | (event: any) => void |
133
+
82
134
  ## 主题定制
83
135
 
84
136
  ### CSS 变量
@@ -1,6 +1,10 @@
1
1
  import { type AvatarProps, type AvatarSlots } from './common';
2
2
  declare function __VLS_template(): Readonly<AvatarSlots> & AvatarSlots;
3
- declare const __VLS_component: import("vue").DefineComponent<AvatarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{}>, {
3
+ declare const __VLS_component: import("vue").DefineComponent<AvatarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
+ click: (event: any) => any;
5
+ }, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{
6
+ onClick?: ((event: any) => any) | undefined;
7
+ }>, {
4
8
  shape: "circle" | "square";
5
9
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
10
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view :class="avatarClass" :style="avatarStyle">
2
+ <view :class="avatarClass" :style="avatarStyle" @click="onClick">
3
3
  <slot>
4
4
  <image
5
5
  v-if="src"
@@ -16,17 +16,30 @@
16
16
  />
17
17
  </slot>
18
18
  <slot name="extra"></slot>
19
+
20
+ <view
21
+ v-if="
22
+ context && context.showRemain && context.total > context.max && isLast
23
+ "
24
+ :class="remainClass"
25
+ @click="context.onRemainClick"
26
+ >
27
+ {{ context.remainText }}
28
+ </view>
19
29
  </view>
20
30
  </template>
21
31
 
22
32
  <script>
23
33
  import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from "vue";
24
- import { computed } from "vue";
34
+ import { computed, inject } from "vue";
25
35
  import { classNames, stringifyStyle, createBem } from "../../utils";
26
36
  import SarIcon from "../icon/icon.vue";
27
37
  import {
28
38
  defaultAvatarProps
29
39
  } from "./common";
40
+ import {
41
+ avatarGroupContextSymbol
42
+ } from "../avatar-group/common";
30
43
  /**
31
44
  * @property {string} rootClass 组件根元素类名,默认值:-。
32
45
  * @property {StyleValue} rootStyle 组件根元素样式,默认值:-。
@@ -34,6 +47,8 @@ import {
34
47
  * @property {string} size 头像尺寸,默认值:-。
35
48
  * @property {string} iconSize 图标尺寸,默认值:-。
36
49
  * @property {string} src 图片类型头像的图片地址,默认值:-。
50
+ * @property {number} index 位于头像组中时必传,当前头像在头像组中的下标,默认值:-。
51
+ * @event {(event: any) => void} click 点击时触发
37
52
  */
38
53
  export default _defineComponent({
39
54
  components: {
@@ -54,14 +69,30 @@ export default _defineComponent({
54
69
  iconSize: { type: String, required: false },
55
70
  background: { type: String, required: false },
56
71
  color: { type: String, required: false },
57
- src: { type: String, required: false }
72
+ src: { type: String, required: false },
73
+ index: { type: Number, required: false }
58
74
  }, defaultAvatarProps),
59
- setup(__props, { expose: __expose }) {
75
+ emits: ["click"],
76
+ setup(__props, { expose: __expose, emit: __emit }) {
60
77
  __expose();
61
78
  const props = __props;
79
+ const emit = __emit;
62
80
  const bem = createBem("avatar");
81
+ const context = inject(
82
+ avatarGroupContextSymbol,
83
+ null
84
+ );
85
+ const isLast = computed(() => context && context.max - 1 === props.index);
86
+ const onClick = (event) => {
87
+ emit("click", event);
88
+ };
63
89
  const avatarClass = computed(() => {
64
- return classNames(bem.b(), bem.m(props.shape), props.rootClass);
90
+ return classNames(
91
+ bem.b(),
92
+ bem.m(props.shape),
93
+ bem.m("in-group", !!context),
94
+ props.rootClass
95
+ );
65
96
  });
66
97
  const avatarStyle = computed(() => {
67
98
  return stringifyStyle(
@@ -70,12 +101,16 @@ export default _defineComponent({
70
101
  height: props.size,
71
102
  color: props.color,
72
103
  fontSize: props.iconSize,
73
- background: props.background
104
+ background: props.background,
105
+ marginLeft: context && props.index !== 0 ? `calc(${props.size ? props.size : `var(--sar-avatar-width)`} * ${-context.coverage})` : void 0
74
106
  },
75
107
  props.rootStyle
76
108
  );
77
109
  });
78
- const __returned__ = { props, bem, avatarClass, avatarStyle, get classNames() {
110
+ const remainClass = computed(() => {
111
+ return classNames(bem.e("remain"));
112
+ });
113
+ const __returned__ = { props, emit, bem, context, isLast, onClick, avatarClass, avatarStyle, remainClass, get classNames() {
79
114
  return classNames;
80
115
  }, SarIcon };
81
116
  return __returned__;
@@ -8,6 +8,7 @@ export interface AvatarProps {
8
8
  background?: string;
9
9
  color?: string;
10
10
  src?: string;
11
+ index?: number;
11
12
  }
12
13
  export declare const defaultAvatarProps: {
13
14
  shape: AvatarProps["shape"];
@@ -16,3 +17,6 @@ export interface AvatarSlots {
16
17
  default?(props: Record<string, never>): any;
17
18
  extra?(props: Record<string, never>): any;
18
19
  }
20
+ export interface AvatarEmits {
21
+ (e: 'click', event: any): void;
22
+ }
@@ -11,6 +11,7 @@
11
11
  height: var(--sar-avatar-height);
12
12
  font-size: var(--sar-avatar-font-size);
13
13
  background-color: var(--sar-avatar-bg);
14
+ border: 1px solid transparent;
14
15
  }
15
16
 
16
17
  @include e(image) {
@@ -26,4 +27,23 @@
26
27
  @include m(square) {
27
28
  border-radius: var(--sar-avatar-square-border-radius);
28
29
  }
30
+
31
+ @include m(in-group) {
32
+ border-color: var(--sar-avatar-border-color);
33
+ }
34
+
35
+ @include e('remain') {
36
+ @include universal;
37
+ justify-content: center;
38
+ align-items: center;
39
+ position: absolute;
40
+ top: 0;
41
+ left: 0;
42
+ width: 100%;
43
+ height: 100%;
44
+ font-size: var(--sar-avatar-remain-font-size);
45
+ color: var(--sar-avatar-remain-color);
46
+ background-color: var(--sar-avatar-remain-bg);
47
+ border-radius: inherit;
48
+ }
29
49
  }
@@ -5,7 +5,12 @@ page,
5
5
  --sar-avatar-height: 128rpx;
6
6
  --sar-avatar-font-size: 64rpx;
7
7
  --sar-avatar-bg: var(--sar-secondary-bg);
8
+ --sar-avatar-border-color: var(--sar-emphasis-bg);
8
9
 
9
10
  --sar-avatar-square-border-radius: var(--sar-rounded);
11
+
12
+ --sar-avatar-remain-bg: var(--sar-mask);
13
+ --sar-avatar-remain-color: var(--sar-white);
14
+ --sar-avatar-remain-font-size: var(--sar-text-base);
10
15
  }
11
16
  // #endvariables
@@ -0,0 +1,17 @@
1
+ import { type AvatarGroupProps, type AvatarGroupSlots } from './common';
2
+ declare function __VLS_template(): Readonly<AvatarGroupSlots> & AvatarGroupSlots;
3
+ declare const __VLS_component: import("vue").DefineComponent<AvatarGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
+ "remain-click": (event: any) => any;
5
+ }, string, import("vue").PublicProps, Readonly<AvatarGroupProps> & Readonly<{
6
+ "onRemain-click"?: ((event: any) => any) | undefined;
7
+ }>, {
8
+ showRemain: boolean;
9
+ coverage: number;
10
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
12
+ export default _default;
13
+ type __VLS_WithTemplateSlots<T, S> = T & {
14
+ new (): {
15
+ $slots: S;
16
+ };
17
+ };
@@ -0,0 +1,75 @@
1
+ <template>
2
+ <view :class="avatarGroupClass" :style="avatarGroupStyle">
3
+ <slot></slot>
4
+ </view>
5
+ </template>
6
+
7
+ <script>
8
+ import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from "vue";
9
+ import { computed, provide, reactive, toRef } from "vue";
10
+ import { classNames, stringifyStyle, createBem } from "../../utils";
11
+ import {
12
+ defaultAvatarGroupProps,
13
+ avatarGroupContextSymbol
14
+ } from "./common";
15
+ /**
16
+ * @property {string} rootClass 组件根元素类名,默认值:-。
17
+ * @property {StyleValue} rootStyle 组件根元素样式,默认值:-。
18
+ * @property {number} max 最大头像展示数量,必填,默认值:-。
19
+ * @property {number} total 总的头像个数,必填,默认值:-。
20
+ * @property {number} coverage 头像间的覆盖面,默认值:0.5。
21
+ * @property {boolean} showRemain 是否显示剩余头像数量,默认值:true。
22
+ * @property {string | boolean} remainText 自定义剩余头像数量的内容,默认值:-。
23
+ * @event {(event: any) => void} remain-click 点击剩余数量时触发
24
+ */
25
+ export default _defineComponent({
26
+ ...{
27
+ options: {
28
+ virtualHost: true,
29
+ styleIsolation: "shared"
30
+ }
31
+ },
32
+ __name: "avatar-group",
33
+ props: _mergeDefaults({
34
+ rootStyle: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
35
+ rootClass: { type: String, required: false },
36
+ max: { type: Number, required: true },
37
+ total: { type: Number, required: true },
38
+ coverage: { type: Number, required: false },
39
+ showRemain: { type: Boolean, required: false },
40
+ remainText: { type: [String, Number], required: false }
41
+ }, defaultAvatarGroupProps),
42
+ emits: ["remain-click"],
43
+ setup(__props, { expose: __expose, emit: __emit }) {
44
+ const props = __props;
45
+ const emit = __emit;
46
+ const bem = createBem("avatar-group");
47
+ provide(
48
+ avatarGroupContextSymbol,
49
+ reactive({
50
+ total: toRef(() => props.total),
51
+ max: toRef(() => props.max),
52
+ showRemain: toRef(() => props.showRemain),
53
+ coverage: toRef(() => props.coverage),
54
+ remainText: toRef(() => props.remainText ?? `+${props.total - props.max}`),
55
+ onRemainClick: (event) => {
56
+ emit("remain-click", event);
57
+ }
58
+ })
59
+ );
60
+ __expose({});
61
+ const avatarGroupClass = computed(() => {
62
+ return classNames(bem.b(), props.rootClass);
63
+ });
64
+ const avatarGroupStyle = computed(() => {
65
+ return stringifyStyle(props.rootStyle);
66
+ });
67
+ const __returned__ = { props, emit, bem, avatarGroupClass, avatarGroupStyle };
68
+ return __returned__;
69
+ }
70
+ });
71
+ </script>
72
+
73
+ <style lang="scss">
74
+ @import './index.scss';
75
+ </style>
@@ -0,0 +1,31 @@
1
+ import { type StyleValue } from 'vue';
2
+ export interface AvatarGroupProps {
3
+ rootStyle?: StyleValue;
4
+ rootClass?: string;
5
+ max: number;
6
+ total: number;
7
+ coverage?: number;
8
+ showRemain?: boolean;
9
+ remainText?: string | number;
10
+ }
11
+ export declare const defaultAvatarGroupProps: {
12
+ coverage: number;
13
+ showRemain: boolean;
14
+ };
15
+ export interface AvatarGroupSlots {
16
+ default?(props: Record<string, never>): any;
17
+ }
18
+ export interface AvatarGroupEmits {
19
+ (e: 'remain-click', event: any): void;
20
+ }
21
+ export interface AvatarGroupExpose {
22
+ }
23
+ export interface AvatarGroupContext {
24
+ total: number;
25
+ max: number;
26
+ showRemain: boolean;
27
+ remainText?: string | number;
28
+ coverage: number;
29
+ onRemainClick: (event: any) => void;
30
+ }
31
+ export declare const avatarGroupContextSymbol: unique symbol;
@@ -0,0 +1,3 @@
1
+ import { defaultConfig } from '../config';
2
+ export const defaultAvatarGroupProps = defaultConfig.avatarGroup;
3
+ export const avatarGroupContextSymbol = Symbol('avatar-group-context');
@@ -0,0 +1 @@
1
+ export type { AvatarGroupProps, AvatarGroupSlots, AvatarGroupEmits, AvatarGroupExpose, } from './common';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ @use '../style/base' as *;
2
+
3
+ @include bem(avatar-group) {
4
+ @include b() {
5
+ @include universal;
6
+ flex-direction: row;
7
+ align-items: center;
8
+ }
9
+ }
@@ -80,6 +80,10 @@ export declare const defaultConfig: {
80
80
  avatar: {
81
81
  shape: AvatarProps["shape"];
82
82
  };
83
+ avatarGroup: {
84
+ coverage: number;
85
+ showRemain: boolean;
86
+ };
83
87
  backTop: {
84
88
  visibleHeight: number;
85
89
  };
@@ -29,6 +29,10 @@ export const defaultConfig = {
29
29
  avatar: {
30
30
  shape: 'circle',
31
31
  },
32
+ avatarGroup: {
33
+ coverage: 0.5,
34
+ showRemain: true,
35
+ },
32
36
  backTop: {
33
37
  visibleHeight: 200,
34
38
  },
@@ -5,7 +5,7 @@ export function getCurrentTime(remainTime) {
5
5
  milliseconds: remainTime % 1000,
6
6
  seconds: ~~(remainTime / 1000) % 60,
7
7
  minutes: ~~(remainTime / 1000 / 60) % 60,
8
- hours: ~~(remainTime / 1000 / 60 / 60) % 60,
8
+ hours: ~~(remainTime / 1000 / 60 / 60) % 24,
9
9
  days: ~~(remainTime / 1000 / 60 / 60 / 24),
10
10
  total: remainTime,
11
11
  };
@@ -1,4 +1,4 @@
1
- import { computed, nextTick, onBeforeUnmount, onMounted, provide, reactive, ref, toRef, watch, } from 'vue';
1
+ import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, provide, reactive, ref, toRef, watch, } from 'vue';
2
2
  import { formItemContextSymbol, useFormContext, } from '../form/common';
3
3
  import { chainGet, chainSet, deepClone, getBoundingClientRect, getScrollIntoViewValue, getViewportScrollInfo, getWindowInfo, noop, toArray, uniqid, } from '../../utils';
4
4
  export function useFormItem(props) {
@@ -137,10 +137,11 @@ export function useFormItem(props) {
137
137
  clearValidate();
138
138
  };
139
139
  const fieldId = uniqid();
140
+ const instance = getCurrentInstance();
140
141
  const scrollToField = async () => {
141
142
  const [scrollInfo, fieldRect, windowInfo] = await Promise.all([
142
143
  getViewportScrollInfo(),
143
- getBoundingClientRect(`.${fieldId}`),
144
+ getBoundingClientRect(`.${fieldId}`, instance),
144
145
  getWindowInfo(),
145
146
  ]);
146
147
  const scrollTop = getScrollIntoViewValue(windowInfo.windowHeight, scrollInfo.scrollTop, fieldRect.height, fieldRect.top + scrollInfo.scrollTop, formContext.scrollIntoViewOptions);
@@ -8,8 +8,8 @@ declare const __VLS_component: import("vue").DefineComponent<PaginationProps, {}
8
8
  "onUpdate:current"?: ((page: number) => any) | undefined;
9
9
  }>, {
10
10
  type: "simple" | "multi";
11
- current: number;
12
11
  total: number;
12
+ current: number;
13
13
  pageSize: number;
14
14
  pageButtonCount: number;
15
15
  multiCount: number;
@@ -13,22 +13,23 @@
13
13
  <view :class="classNames(bem.e('header'), bem.em('header', props.type))">
14
14
  <view v-if="type === 'compact'" :class="bem.e('button-wrap')">
15
15
  <slot
16
+ v-if="$slots.cancel"
16
17
  name="cancel"
17
18
  :on-click="onCancel"
18
19
  :loading="loading.cancel"
19
20
  :text="mergedCancelText"
21
+ ></slot>
22
+ <sar-button
23
+ v-if="!$slots.cancel"
24
+ type="pale-text"
25
+ theme="neutral"
26
+ :root-class="classNames(bem.e('header-cancel'))"
27
+ :loading="loading.cancel"
28
+ block
29
+ @click="onCancel"
20
30
  >
21
- <sar-button
22
- type="pale-text"
23
- theme="neutral"
24
- :root-class="classNames(bem.e('header-cancel'))"
25
- :loading="loading.cancel"
26
- block
27
- @click="onCancel"
28
- >
29
- {{ mergedCancelText }}
30
- </sar-button>
31
- </slot>
31
+ {{ mergedCancelText }}
32
+ </sar-button>
32
33
  </view>
33
34
  <slot name="title-prepend"></slot>
34
35
  <view :class="bem.e('title')">
@@ -39,24 +40,25 @@
39
40
  </view>
40
41
  <view v-if="type === 'compact'" :class="bem.e('button-wrap')">
41
42
  <slot
43
+ v-if="$slots.confirm"
42
44
  name="confirm"
43
45
  :on-click="onConfirm"
44
46
  :disabled="confirmDisabled"
45
47
  :loading="loading.confirm"
46
48
  :text="mergedConfirmText"
49
+ ></slot>
50
+ <sar-button
51
+ v-if="!$slots.confirm"
52
+ type="pale-text"
53
+ theme="primary"
54
+ :root-class="classNames(bem.e('header-confirm'))"
55
+ :loading="loading.confirm"
56
+ :disabled="confirmDisabled"
57
+ block
58
+ @click="onConfirm"
47
59
  >
48
- <sar-button
49
- type="pale-text"
50
- theme="primary"
51
- :root-class="classNames(bem.e('header-confirm'))"
52
- :loading="loading.confirm"
53
- :disabled="confirmDisabled"
54
- block
55
- @click="onConfirm"
56
- >
57
- {{ mergedConfirmText }}
58
- </sar-button>
59
- </slot>
60
+ {{ mergedConfirmText }}
61
+ </sar-button>
60
62
  </view>
61
63
  <view
62
64
  v-if="type === 'loose' && showClose"
@@ -72,45 +74,45 @@
72
74
  <slot name="visible" :whole="wholeVisible" :already="already"></slot>
73
75
  <view v-if="showFooter && type === 'loose'" :class="bem.e('footer')">
74
76
  <slot
77
+ v-if="$slots.cancel"
75
78
  name="cancel"
76
79
  :on-click="onCancel"
77
80
  :visible="showCancel"
78
81
  :loading="loading.cancel"
79
82
  :text="mergedCancelText"
83
+ ></slot>
84
+ <sar-button
85
+ v-if="!$slots.cancel && showCancel"
86
+ type="pale"
87
+ theme="primary"
88
+ round
89
+ :loading="loading.cancel"
90
+ block
91
+ @click="onCancel"
80
92
  >
81
- <sar-button
82
- v-if="showCancel"
83
- type="pale"
84
- theme="primary"
85
- round
86
- :loading="loading.cancel"
87
- block
88
- @click="onCancel"
89
- >
90
- {{ mergedCancelText }}
91
- </sar-button>
92
- </slot>
93
+ {{ mergedCancelText }}
94
+ </sar-button>
93
95
  <slot
96
+ v-if="$slots.confirm"
94
97
  name="confirm"
95
98
  :visible="showConfirm"
96
99
  :on-click="onConfirm"
97
100
  :disabled="confirmDisabled"
98
101
  :loading="loading.confirm"
99
102
  :text="mergedConfirmText"
103
+ ></slot>
104
+ <sar-button
105
+ v-if="!$slots.confirm && showConfirm"
106
+ type="default"
107
+ theme="primary"
108
+ round
109
+ :loading="loading.confirm"
110
+ :disabled="confirmDisabled"
111
+ block
112
+ @click="onConfirm"
100
113
  >
101
- <sar-button
102
- v-if="showConfirm"
103
- type="default"
104
- theme="primary"
105
- round
106
- :loading="loading.confirm"
107
- :disabled="confirmDisabled"
108
- block
109
- @click="onConfirm"
110
- >
111
- {{ mergedConfirmText }}
112
- </sar-button>
113
- </slot>
114
+ {{ mergedConfirmText }}
115
+ </sar-button>
114
116
  </view>
115
117
  </view>
116
118
  </sar-popup>
@@ -1,8 +1,8 @@
1
1
  import { type SwiperDotProps } from './common';
2
2
  declare const _default: import("vue").DefineComponent<SwiperDotProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<SwiperDotProps> & Readonly<{}>, {
3
3
  type: "dot" | "dot-bar" | "index" | "title" | "fraction";
4
- current: number;
5
4
  total: number;
5
+ current: number;
6
6
  field: string;
7
7
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
8
  export default _default;
@@ -0,0 +1,14 @@
1
+ {
2
+ "format": 2,
3
+ "compileOptions": {
4
+ "component2": true,
5
+ "enableNodeModuleBabelTransform": true
6
+ },
7
+ "unknownConfig": {
8
+ "appid": "touristappid",
9
+ "projectname": "SardUniapp"
10
+ },
11
+ "developOptions": {
12
+ "skipTranspile": true
13
+ }
14
+ }
package/global.d.ts CHANGED
@@ -5,6 +5,7 @@ declare module 'vue' {
5
5
  SarActionSheet: typeof import('./components/action-sheet/action-sheet').default
6
6
  SarAlert: typeof import('./components/alert/alert').default
7
7
  SarAvatar: typeof import('./components/avatar/avatar').default
8
+ SarAvatarGroup: typeof import('./components/avatar-group/avatar-group').default
8
9
  SarBackTop: typeof import('./components/back-top/back-top').default
9
10
  SarBadge: typeof import('./components/badge/badge').default
10
11
  SarButton: typeof import('./components/button/button').default
package/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './components/accordion';
2
2
  export * from './components/action-sheet';
3
3
  export * from './components/alert';
4
4
  export * from './components/avatar';
5
+ export * from './components/avatar-group';
5
6
  export * from './components/back-top';
6
7
  export * from './components/badge';
7
8
  export * from './components/button';
package/index.js CHANGED
@@ -2,6 +2,7 @@ export * from './components/accordion';
2
2
  export * from './components/action-sheet';
3
3
  export * from './components/alert';
4
4
  export * from './components/avatar';
5
+ export * from './components/avatar-group';
5
6
  export * from './components/back-top';
6
7
  export * from './components/badge';
7
8
  export * from './components/button';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": "sard-uniapp",
3
3
  "name": "sard-uniapp",
4
4
  "displayName": "sard-uniapp",
5
- "version": "1.24.3",
5
+ "version": "1.24.5",
6
6
  "description": "sard-uniapp 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库",
7
7
  "main": "index.js",
8
8
  "scripts": {
package/utils/dom.js CHANGED
@@ -26,7 +26,10 @@ export function getBoundingClientRect(selector, instance) {
26
26
  */
27
27
  export function getWindowInfo() {
28
28
  if (uni.getWindowInfo) {
29
- return uni.getWindowInfo();
29
+ const windowInfo = uni.getWindowInfo();
30
+ if (windowInfo.safeAreaInsets) {
31
+ return windowInfo;
32
+ }
30
33
  }
31
34
  const info = uni.getSystemInfoSync();
32
35
  return {