savor-ui 0.24.0 → 0.24.1

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
@@ -2,6 +2,13 @@
2
2
 
3
3
 
4
4
 
5
+ ## [0.24.1](https://gitee.com/mach552/savor-ui/compare/v0.24.0...v0.24.1) (2026-08-24)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **dropdown:** 修复插槽元素被包裹的问题 ([2fb1603](https://gitee.com/mach552/savor-ui/commits/2fb1603e030e0484bde2541e2251fc505f2830d5))
11
+
5
12
  # [0.24.0](https://gitee.com/mach552/savor-ui/compare/v0.23.1...v0.24.0) (2026-08-24)
6
13
 
7
14
 
@@ -2,32 +2,35 @@ import { useNamespace as e } from "../../../hooks/src/use-namespace.mjs";
2
2
  import "../../../hooks/index.mjs";
3
3
  import { SPopover as t } from "../popover/index.mjs";
4
4
  import { dropdownContextKey as n } from "./types.mjs";
5
- import { createComponent as r, createSlot as i, defineVaporComponent as a, provide as o, renderEffect as s, setClass as c, setInsertionState as l, setStaticTemplateRef as u, template as d, unref as f, useTemplateRef as p } from "vue";
5
+ import { child as r, createComponent as i, createSlot as a, defineVaporComponent as o, provide as s, renderEffect as c, setClass as l, setInsertionState as u, setStaticTemplateRef as d, template as f, unref as p, useTemplateRef as m } from "vue";
6
6
  //#region ../components/src/dropdown/dropdown.vue?vue&type=script&setup=true&vapor=true&lang.ts
7
- var m = d("<div>"), h = d("<div>", 1), g = /*@__PURE__*/ a({
7
+ var h = f("<div><div>"), g = /*@__PURE__*/ o({
8
8
  name: "SDropdown",
9
9
  __name: "dropdown",
10
10
  props: { popoverProps: {} },
11
- setup(a) {
12
- let d = e("dropdown"), g = p("popoverRef"), _ = null, v = () => {
11
+ setup(o) {
12
+ let f = e("dropdown"), g = m("popoverRef"), _ = null, v = () => {
13
13
  _ &&= (_(), null);
14
14
  };
15
- o(n, { itemClick: () => (g.value?.hide(), new Promise((e) => {
15
+ s(n, { itemClick: () => (g.value?.hide(), new Promise((e) => {
16
16
  _ = e;
17
17
  })) });
18
- let y = h();
19
- return s(() => c(y, [f(d).b()])), l(y, null, 0), u(r(f(t), { $: [() => ({
18
+ let y = i(p(t), { $: [() => ({
20
19
  trigger: "click",
21
- placement: a.popoverProps?.trigger === "contextmenu" ? "bottom-start" : "bottom",
22
- alignPoint: a.popoverProps?.trigger === "contextmenu",
23
- ...a.popoverProps
20
+ placement: o.popoverProps?.trigger === "contextmenu" ? "bottom-start" : "bottom",
21
+ alignPoint: o.popoverProps?.trigger === "contextmenu",
22
+ ...o.popoverProps
24
23
  }), { onAfterLeave: () => v }] }, {
25
24
  content: () => {
26
- let e = m();
27
- return s(() => c(e, f(d).e("list"))), l(e, null, 0), i("content"), e;
25
+ let e = h(), t = r(e);
26
+ return c(() => {
27
+ let n = p(f);
28
+ l(e, [n.b()]), l(t, n.e("list"));
29
+ }), u(t, null, 0), a("content"), e;
28
30
  },
29
- default: () => i("default", null, null, 4)
30
- }), g, null, "popoverRef"), y;
31
+ default: () => a("default", null, null, 4)
32
+ }, !0);
33
+ return d(y, g, null, "popoverRef"), y;
31
34
  }
32
35
  });
33
36
  //#endregion
@@ -1,24 +1,23 @@
1
+ import { SkeletonSlots } from './types';
1
2
  import { PublicProps, VNode, Plugin } from 'vue';
2
3
  export declare const SSkeleton: ((__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
3
4
  attrs: any;
4
- slots: {};
5
+ slots: SkeletonSlots;
5
6
  emit: {};
6
7
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
7
8
  props: PublicProps & {
8
- animation?: boolean | undefined;
9
- type?: "line" | "square" | "circle" | undefined;
10
- size?: "mini" | "small" | "medium" | "large" | "larger" | undefined;
11
- rows?: number | undefined;
12
- widths?: Array<string | number> | undefined;
13
- lineHeight?: string | number | undefined;
14
- lineSpacing?: string | number | undefined;
15
- squareStyle?: Record<string, string> | undefined;
9
+ loading?: boolean | undefined;
10
+ animate?: "pulse" | "shimmer" | "solid" | undefined;
11
+ color?: string | undefined;
12
+ stagger?: number | undefined;
13
+ leafTags?: string[] | undefined;
14
+ exclude?: string[] | undefined;
16
15
  } & (typeof globalThis extends {
17
16
  __VLS_PROPS_FALLBACK: infer P;
18
17
  } ? P : {});
19
18
  expose: (exposed: {}) => void;
20
19
  attrs: any;
21
- slots: {};
20
+ slots: SkeletonSlots;
22
21
  emit: {};
23
22
  }>) => VNode & {
24
23
  __ctx?: Awaited<typeof __VLS_setup>;
@@ -1,4 +1,4 @@
1
- import { SkeletonProps } from './types';
1
+ import { SkeletonProps, SkeletonSlots } from './types';
2
2
  import { PublicProps, VNode } from 'vue';
3
3
  declare const __VLS_export: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: PublicProps & __VLS_PrettifyLocal<SkeletonProps> & (typeof globalThis extends {
@@ -6,7 +6,7 @@ declare const __VLS_export: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup
6
6
  } ? P : {});
7
7
  expose: (exposed: {}) => void;
8
8
  attrs: any;
9
- slots: {};
9
+ slots: SkeletonSlots;
10
10
  emit: {};
11
11
  }>) => VNode & {
12
12
  __ctx?: Awaited<typeof __VLS_setup>;
@@ -1,53 +1,111 @@
1
- import { getSize as e } from "../../../utils/src/tool.mjs";
2
- import "../../../utils/index.mjs";
3
- import { useNamespace as t } from "../../../hooks/src/use-namespace.mjs";
1
+ import { useNamespace as e } from "../../../hooks/src/use-namespace.mjs";
4
2
  import "../../../hooks/index.mjs";
5
- import { createFor as n, createIf as r, defineVaporComponent as i, renderEffect as a, setClass as o, setInsertionState as s, setStyle as c, template as l, unref as u } from "vue";
3
+ import { child as t, createFor as n, createIf as r, createSlot as i, defineVaporComponent as a, onMounted as o, onUnmounted as s, ref as c, renderEffect as l, setAttr as u, setClass as d, setInsertionState as f, setStaticTemplateRef as p, setStyle as m, template as h, unref as g, useTemplateRef as _, watch as v } from "vue";
6
4
  //#region ../components/src/skeleton/skeleton.vue?vue&type=script&setup=true&vapor=true&lang.ts
7
- var d = l("<div>"), f = l("<div>", 1), p = /*@__PURE__*/ i({
5
+ var y = h("<div>"), b = h("<div><div></div>", 1), x = /*@__PURE__*/ a({
8
6
  name: "SSkeleton",
9
7
  __name: "skeleton",
10
8
  props: {
11
- animation: { type: Boolean },
12
- type: { default: "line" },
13
- size: { default: "medium" },
14
- rows: { default: 1 },
15
- widths: {},
16
- lineHeight: { default: "20px" },
17
- lineSpacing: { default: "8px" },
18
- squareStyle: {}
9
+ loading: { type: Boolean },
10
+ animate: { default: "pulse" },
11
+ color: {},
12
+ stagger: { default: 80 },
13
+ leafTags: {},
14
+ exclude: {}
19
15
  },
20
- setup(i) {
21
- let l = t("skeleton"), p = f();
22
- return a(() => {
23
- let e = u(l);
24
- o(p, [e.b(), e.is("animation", i.animation)]);
25
- }), s(p, null, 0), r(() => i.type === "line", () => {
26
- let t = d();
27
- return a(() => {
28
- o(t, [u(l).e("line")]), c(t, { gap: u(e)(i.lineSpacing) });
29
- }), s(t, null, 0), n(() => i.rows, (t, n) => {
30
- let r = d();
31
- return a(() => {
32
- let t = u(e);
33
- o(r, [u(l).e("line-item")]), c(r, {
34
- height: t(i.lineHeight),
35
- width: t(i.widths?.[n.value] || "100%")
16
+ setup(a) {
17
+ let h = a, x = e("skeleton"), S = _("contentRef"), C = c([]), w = new Set([
18
+ "p",
19
+ "h1",
20
+ "h2",
21
+ "h3",
22
+ "h4",
23
+ "h5",
24
+ "h6",
25
+ "li",
26
+ "td",
27
+ "th"
28
+ ]);
29
+ function T(e, t) {
30
+ let n = parseFloat(e.borderTopLeftRadius) || 0, r = parseFloat(e.borderTopRightRadius) || 0, i = parseFloat(e.borderBottomRightRadius) || 0, a = parseFloat(e.borderBottomLeftRadius) || 0;
31
+ if (n === 0 && r === 0 && i === 0 && a === 0) return;
32
+ if (e.borderRadius === "50%") return "50%";
33
+ let o = t.getBoundingClientRect(), s = o.width > 0 && o.height > 0 && Math.abs(o.width - o.height) < 4;
34
+ return Math.max(n, r, i, a) > 9998 ? s ? "50%" : 9999 : n === r && r === i && i === a ? n === 8 ? void 0 : n : `${n}px ${r}px ${i}px ${a}px`;
35
+ }
36
+ function E(e) {
37
+ let t = e.getBoundingClientRect();
38
+ if (t.width <= 0) return [];
39
+ let n = [], r = h.leafTags ? new Set([...w, ...h.leafTags.map((e) => e.toLowerCase())]) : w, i = h.exclude, a = (e) => {
40
+ let o = window.getComputedStyle(e);
41
+ if (o.display === "none" || o.opacity === "0" || i?.some((t) => e.matches(t))) return;
42
+ let s = e.tagName.toLowerCase(), c = Array.from(e.children).filter((e) => {
43
+ let t = window.getComputedStyle(e);
44
+ return t.display !== "none" && t.opacity !== "0";
45
+ }), l = s === "img" || s === "svg" || s === "video" || s === "canvas", u = s === "input" || s === "button" || s === "textarea" || s === "select";
46
+ if (c.length === 0 || l || u || r.has(s)) {
47
+ let r = e.getBoundingClientRect();
48
+ if (r.width < 1 || r.height < 1) return;
49
+ let i = l && Math.abs(r.width - r.height) < 4;
50
+ n.push({
51
+ x: +((r.left - t.left) / t.width * 100).toFixed(4),
52
+ y: Math.round(r.top - t.top),
53
+ w: +(r.width / t.width * 100).toFixed(4),
54
+ h: Math.round(r.height),
55
+ r: i ? "50%" : T(o, e) ?? 8
36
56
  });
37
- }), r;
38
- }, (e, t) => e, 9), t;
39
- }, () => r(() => i.type === "square" || i.type === "circle", () => {
40
- let e = d();
41
- return a(() => {
42
- let t = u(l);
43
- o(e, [
44
- t.e("shape"),
45
- t.m(i.size),
46
- t.is("circle", i.type === "circle")
47
- ]), c(e, i.squareStyle);
48
- }), e;
49
- }), 261), p;
57
+ return;
58
+ }
59
+ for (let e of c) a(e);
60
+ };
61
+ for (let t of e.children) a(t);
62
+ return n;
63
+ }
64
+ let D = () => {
65
+ S.value && (C.value = E(S.value));
66
+ }, O = 0, k = () => {
67
+ O ||= requestAnimationFrame(() => {
68
+ O = 0, D();
69
+ });
70
+ }, A = (e, t) => {
71
+ let n = {
72
+ left: `${e.x}%`,
73
+ top: `${e.y}px`,
74
+ width: `${e.w}%`,
75
+ height: `${e.h}px`,
76
+ borderRadius: typeof e.r == "number" ? `${e.r}px` : e.r
77
+ };
78
+ return h.color && (n.backgroundColor = h.color), h.stagger > 0 && h.animate !== "solid" && (n.animationDelay = `${t * h.stagger}ms`), n;
79
+ }, j = null, M = null;
80
+ v(() => h.loading, (e) => {
81
+ e && k();
82
+ }), o(() => {
83
+ D(), j = new MutationObserver((e) => {
84
+ e.length === 1 && e[0].target === S.value && e[0].attributeName === "class" || k();
85
+ }), j.observe(S.value, {
86
+ childList: !0,
87
+ subtree: !0,
88
+ attributes: !0,
89
+ attributeFilter: ["class", "style"]
90
+ }), M = new ResizeObserver(k), M.observe(S.value), document.fonts?.ready.then(D);
91
+ }), s(() => {
92
+ j?.disconnect(), M?.disconnect(), O && cancelAnimationFrame(O);
93
+ });
94
+ let N = b(), P = t(N);
95
+ return l(() => {
96
+ let e = g(x), t = a.loading;
97
+ d(N, e.b()), u(N, "aria-busy", t || void 0), d(P, [e.e("content"), e.is("loading", t)]);
98
+ }), f(P, null, 0), i(), p(P, S, null, "contentRef"), f(N, null, 1), r(() => a.loading && C.value.length, () => {
99
+ let e = y();
100
+ return l(() => d(e, g(x).e("overlay"))), f(e, null, 0), n(() => C.value, (e, t) => {
101
+ let n = y();
102
+ return l(() => {
103
+ let r = g(x);
104
+ d(n, [r.e("bone"), r.m("bone", a.animate)]), m(n, A(e.value, t.value));
105
+ }), n;
106
+ }, (e, t) => t, 9), e;
107
+ }), N;
50
108
  }
51
109
  });
52
110
  //#endregion
53
- export { p as default };
111
+ export { x as default };
@@ -1,18 +1,31 @@
1
+ /** 单个骨架块(从子 DOM 抓取的几何信息) */
2
+ export interface SkeletonBone {
3
+ /** 相对容器左侧的位置(百分比,容器宽度为 100) */
4
+ x: number;
5
+ /** 相对容器顶部的位置(px) */
6
+ y: number;
7
+ /** 宽度(百分比,容器宽度为 100) */
8
+ w: number;
9
+ /** 高度(px) */
10
+ h: number;
11
+ /** 圆角:px 数值或 '50%' 等 CSS 值 */
12
+ r: number | string;
13
+ }
1
14
  export interface SkeletonProps {
2
- /** 是否显示动画 */
3
- animation?: boolean;
4
- /** 类型 */
5
- type?: "line" | "square" | "circle";
6
- /** 大小 */
7
- size?: "mini" | "small" | "medium" | "large" | "larger";
8
- /** 行数 */
9
- rows?: number;
10
- /** 宽度列表 */
11
- widths?: Array<string | number>;
12
- /** 行高 */
13
- lineHeight?: string | number;
14
- /** 行间距 */
15
- lineSpacing?: string | number;
16
- /** square | circle 类型样式*/
17
- squareStyle?: Record<string, string>;
15
+ /** 是否处于加载中(加载中显示骨架屏,隐藏真实内容但保留布局) */
16
+ loading?: boolean;
17
+ /** 动画风格 */
18
+ animate?: "pulse" | "shimmer" | "solid";
19
+ /** 骨架块颜色,默认取主题 fill-2 颜色 */
20
+ color?: string;
21
+ /** 骨架块逐个出现的间隔(ms) */
22
+ stagger?: number;
23
+ /** 额外视为叶子节点的标签名(这些标签整体生成一块骨架,不再向下拆分) */
24
+ leafTags?: string[];
25
+ /** 排除的选择器列表(匹配的元素及其子元素不生成骨架) */
26
+ exclude?: string[];
27
+ }
28
+ export interface SkeletonSlots {
29
+ /** 骨架屏覆盖的元素 */
30
+ default: () => any;
18
31
  }
@@ -7,10 +7,13 @@
7
7
  flex-direction: column;
8
8
  align-items: center;
9
9
  justify-content: center;
10
+ gap: 12px;
10
11
  @include e(image) {
11
- margin-bottom: 20px;
12
12
  font-size: 50px;
13
13
  color: getCssVar("color", "text-3");
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
14
17
  }
15
18
  @include e(description) {
16
19
  font-size: 14px;
@@ -10,4 +10,9 @@
10
10
  > * {
11
11
  flex-shrink: 0;
12
12
  }
13
+ @include e(excess){
14
+ height: 100%;
15
+ display: flex;
16
+ align-items: center;
17
+ }
13
18
  }
@@ -1,58 +1,86 @@
1
- @use "../mixins/function.scss" as *;
2
- @use "../mixins/mixins.scss" as *;
3
- @use "../common/var.scss" as *;
4
-
5
- @include b(skeleton) {
6
- @include when(animation) {
7
- @include be(skeleton, line-item) {
8
- background: linear-gradient(
9
- 90deg,
10
- getCssVar("color", "fill-2") 25%,
11
- getCssVar("color", "fill-3") 37%,
12
- getCssVar("color", "fill-2") 63%
13
- );
14
- background-size: 400% 100%;
15
- animation: skeleton-animation 1.5s cubic-bezier(0, 0, 1, 1) infinite;
16
- }
17
- @include be(skeleton, shape) {
18
- background: linear-gradient(
19
- 90deg,
20
- getCssVar("color", "fill-2") 25%,
21
- getCssVar("color", "fill-3") 37%,
22
- getCssVar("color", "fill-2") 63%
23
- );
24
- background-size: 400% 100%;
25
- animation: skeleton-animation 1.5s cubic-bezier(0, 0, 1, 1) infinite;
26
- }
27
- }
28
- @include e(line) {
29
- display: flex;
30
- flex-direction: column;
31
- }
32
- @include e(line-item) {
33
- height: 20px;
34
- background-color: getCssVar("color", "fill-2");
35
- }
36
- @include e(shape) {
37
- background-color: getCssVar("color", "fill-2");
38
- @include when(circle) {
39
- border-radius: getCssVar("radius", "circle");
40
- }
41
- }
42
- @each $size in $size-list {
43
- @include m($size) {
44
- height: getCssVar("size", $size);
45
- width: getCssVar("size", $size);
46
- border-radius: getCssVar("radius", $size);
47
- }
48
- }
49
-
50
- @keyframes skeleton-animation {
51
- 0% {
52
- background-position: 100% 50%;
53
- }
54
- 100% {
55
- background-position: 0 50%;
56
- }
57
- }
58
- }
1
+ @use "../mixins/function.scss" as *;
2
+ @use "../mixins/mixins.scss" as *;
3
+ @use "../common/var.scss" as *;
4
+
5
+ @include b(skeleton) {
6
+ position: relative;
7
+
8
+ @include be(skeleton, content) {
9
+ @include when(loading) {
10
+ visibility: hidden;
11
+ }
12
+ }
13
+
14
+ @include be(skeleton, overlay) {
15
+ position: absolute;
16
+ inset: 0;
17
+ overflow: hidden;
18
+ pointer-events: none;
19
+ }
20
+
21
+ @include be(skeleton, bone) {
22
+ position: absolute;
23
+ background-color: getCssVar("color", "fill-2");
24
+ animation: skeleton-appear 0.3s ease-out backwards;
25
+
26
+ @include m(pulse) {
27
+ &::after {
28
+ content: "";
29
+ position: absolute;
30
+ inset: 0;
31
+ border-radius: inherit;
32
+ background-color: getCssVar("color", "fill-3");
33
+ animation: skeleton-pulse 1.6s ease-in-out infinite;
34
+ }
35
+ }
36
+
37
+ @include m(shimmer) {
38
+ &::after {
39
+ content: "";
40
+ position: absolute;
41
+ inset: 0;
42
+ border-radius: inherit;
43
+ background: linear-gradient(
44
+ 90deg,
45
+ transparent 25%,
46
+ getCssVar("color", "fill-3") 50%,
47
+ transparent 75%
48
+ );
49
+ background-size: 200% 100%;
50
+ animation: skeleton-shimmer 3s linear infinite;
51
+ }
52
+ }
53
+
54
+ @include m(solid) {
55
+ animation: none;
56
+ }
57
+ }
58
+
59
+ @keyframes skeleton-appear {
60
+ from {
61
+ opacity: 0;
62
+ }
63
+ to {
64
+ opacity: 1;
65
+ }
66
+ }
67
+
68
+ @keyframes skeleton-pulse {
69
+ 0%,
70
+ 100% {
71
+ opacity: 0;
72
+ }
73
+ 50% {
74
+ opacity: 1;
75
+ }
76
+ }
77
+
78
+ @keyframes skeleton-shimmer {
79
+ 0% {
80
+ background-position: 200% 0;
81
+ }
82
+ 100% {
83
+ background-position: -200% 0;
84
+ }
85
+ }
86
+ }
@@ -2102,33 +2102,26 @@
2102
2102
  "s-select/popoverProps": {
2103
2103
  "description": "弹出层属性 [PopoverProps](/components/other/popover#popover-props)"
2104
2104
  },
2105
- "s-skeleton/animation": {
2106
- "description": "是否显示动画",
2105
+ "s-skeleton/loading": {
2106
+ "description": "是否处于加载中(加载中显示骨架屏,隐藏真实内容但保留布局)",
2107
2107
  "type": "boolean"
2108
2108
  },
2109
- "s-skeleton/type": {
2110
- "description": "类型"
2109
+ "s-skeleton/animate": {
2110
+ "description": "动画风格"
2111
2111
  },
2112
- "s-skeleton/size": {
2113
- "description": "大小"
2112
+ "s-skeleton/color": {
2113
+ "description": "骨架块颜色,默认取主题 fill-2 颜色",
2114
+ "type": "string"
2114
2115
  },
2115
- "s-skeleton/rows": {
2116
- "description": "行数",
2116
+ "s-skeleton/stagger": {
2117
+ "description": "骨架块逐个出现的间隔(ms)",
2117
2118
  "type": "number"
2118
2119
  },
2119
- "s-skeleton/widths": {
2120
- "description": "宽度列表"
2121
- },
2122
- "s-skeleton/lineHeight": {
2123
- "description": "行高",
2124
- "type": "string | number"
2125
- },
2126
- "s-skeleton/lineSpacing": {
2127
- "description": "行间距",
2128
- "type": "string | number"
2120
+ "s-skeleton/leafTags": {
2121
+ "description": "额外视为叶子节点的标签名(这些标签整体生成一块骨架,不再向下拆分)"
2129
2122
  },
2130
- "s-skeleton/squareStyle": {
2131
- "description": "square | circle 类型样式"
2123
+ "s-skeleton/exclude": {
2124
+ "description": "排除的选择器列表(匹配的元素及其子元素不生成骨架)"
2132
2125
  },
2133
2126
  "s-slider-verify/result": {
2134
2127
  "description": "是否通过验证(v-model:result)",
@@ -876,14 +876,12 @@
876
876
  },
877
877
  "s-skeleton": {
878
878
  "attributes": [
879
- "animation",
880
- "type",
881
- "size",
882
- "rows",
883
- "widths",
884
- "lineHeight",
885
- "lineSpacing",
886
- "squareStyle"
879
+ "loading",
880
+ "animate",
881
+ "color",
882
+ "stagger",
883
+ "leafTags",
884
+ "exclude"
887
885
  ]
888
886
  },
889
887
  "s-slider-verify": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
3
3
  "framework": "vue",
4
4
  "name": "savor-ui",
5
- "version": "0.23.1",
5
+ "version": "0.24.0",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "types-syntax": "typescript",
@@ -5453,72 +5453,61 @@
5453
5453
  "name": "s-skeleton",
5454
5454
  "attributes": [
5455
5455
  {
5456
- "name": "animation",
5457
- "description": "是否显示动画",
5456
+ "name": "loading",
5457
+ "description": "是否处于加载中(加载中显示骨架屏,隐藏真实内容但保留布局)",
5458
5458
  "value": {
5459
5459
  "type": "boolean",
5460
5460
  "kind": "expression"
5461
5461
  }
5462
5462
  },
5463
5463
  {
5464
- "name": "type",
5465
- "description": "类型",
5464
+ "name": "animate",
5465
+ "description": "动画风格",
5466
5466
  "value": {
5467
- "type": "line | square | circle",
5467
+ "type": "pulse | shimmer | solid",
5468
5468
  "kind": "expression"
5469
5469
  }
5470
5470
  },
5471
5471
  {
5472
- "name": "size",
5473
- "description": "大小",
5472
+ "name": "color",
5473
+ "description": "骨架块颜色,默认取主题 fill-2 颜色",
5474
5474
  "value": {
5475
- "type": "mini | small | medium | large | larger",
5475
+ "type": "string",
5476
5476
  "kind": "expression"
5477
5477
  }
5478
5478
  },
5479
5479
  {
5480
- "name": "rows",
5481
- "description": "行数",
5480
+ "name": "stagger",
5481
+ "description": "骨架块逐个出现的间隔(ms)",
5482
5482
  "value": {
5483
5483
  "type": "number",
5484
5484
  "kind": "expression"
5485
5485
  }
5486
5486
  },
5487
5487
  {
5488
- "name": "widths",
5489
- "description": "宽度列表",
5490
- "value": {
5491
- "type": "Array<string | number>",
5492
- "kind": "expression"
5493
- }
5494
- },
5495
- {
5496
- "name": "lineHeight",
5497
- "description": "行高",
5498
- "value": {
5499
- "type": "string | number",
5500
- "kind": "expression"
5501
- }
5502
- },
5503
- {
5504
- "name": "lineSpacing",
5505
- "description": "行间距",
5488
+ "name": "leafTags",
5489
+ "description": "额外视为叶子节点的标签名(这些标签整体生成一块骨架,不再向下拆分)",
5506
5490
  "value": {
5507
- "type": "string | number",
5491
+ "type": "string[]",
5508
5492
  "kind": "expression"
5509
5493
  }
5510
5494
  },
5511
5495
  {
5512
- "name": "squareStyle",
5513
- "description": "square | circle 类型样式",
5496
+ "name": "exclude",
5497
+ "description": "排除的选择器列表(匹配的元素及其子元素不生成骨架)",
5514
5498
  "value": {
5515
- "type": "Record<string, string>",
5499
+ "type": "string[]",
5516
5500
  "kind": "expression"
5517
5501
  }
5518
5502
  }
5519
5503
  ],
5520
5504
  "events": [],
5521
- "slots": []
5505
+ "slots": [
5506
+ {
5507
+ "name": "default",
5508
+ "description": "骨架屏覆盖的元素"
5509
+ }
5510
+ ]
5522
5511
  },
5523
5512
  {
5524
5513
  "name": "s-slider-verify",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "savor-ui",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "description": "A Vue3 Components Library",
5
5
  "keywords": [
6
6
  "component library",