@marianmeres/stuic 2.22.0 → 2.23.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.
- package/dist/components/Skeleton/Skeleton.svelte +127 -0
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +33 -0
- package/dist/components/Skeleton/index.css +62 -0
- package/dist/components/Skeleton/index.d.ts +1 -0
- package/dist/components/Skeleton/index.js +1 -0
- package/dist/components/Switch/Switch.svelte +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
|
|
4
|
+
export interface Props extends Omit<
|
|
5
|
+
HTMLAttributes<HTMLDivElement>,
|
|
6
|
+
"children" | "class"
|
|
7
|
+
> {
|
|
8
|
+
/** Shape variant */
|
|
9
|
+
variant?: "text" | "circle" | "rectangle";
|
|
10
|
+
/** Width (e.g., "100%", "200px") */
|
|
11
|
+
width?: string;
|
|
12
|
+
/** Height (e.g., "1rem", "40px") */
|
|
13
|
+
height?: string;
|
|
14
|
+
/** Shorthand for circle size (sets both width & height) */
|
|
15
|
+
size?: string;
|
|
16
|
+
/** Number of text lines (for text variant) */
|
|
17
|
+
lines?: number;
|
|
18
|
+
/** Gap between lines (for text variant) */
|
|
19
|
+
gap?: string;
|
|
20
|
+
/** Last line width (for text variant) */
|
|
21
|
+
lastLineWidth?: string;
|
|
22
|
+
/** Animation style */
|
|
23
|
+
animation?: "shimmer" | "pulse" | "none";
|
|
24
|
+
/** Animation duration */
|
|
25
|
+
duration?: string;
|
|
26
|
+
/** Border radius (boolean for default, string for custom) */
|
|
27
|
+
rounded?: boolean | string;
|
|
28
|
+
/** Accessibility label */
|
|
29
|
+
ariaLabel?: string;
|
|
30
|
+
/** Bindable element reference */
|
|
31
|
+
el?: HTMLDivElement;
|
|
32
|
+
/** CSS class */
|
|
33
|
+
class?: string | string[];
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<script lang="ts">
|
|
38
|
+
import "./index.css";
|
|
39
|
+
import { twMerge } from "../../utils/tw-merge.js";
|
|
40
|
+
import { prefersReducedMotion } from "../../utils/prefers-reduced-motion.svelte.js";
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
variant = "rectangle",
|
|
44
|
+
width,
|
|
45
|
+
height,
|
|
46
|
+
size,
|
|
47
|
+
lines = 1,
|
|
48
|
+
gap = "0.5rem",
|
|
49
|
+
lastLineWidth = "75%",
|
|
50
|
+
animation = "shimmer",
|
|
51
|
+
duration = "1.5s",
|
|
52
|
+
rounded = true,
|
|
53
|
+
ariaLabel,
|
|
54
|
+
el = $bindable(),
|
|
55
|
+
class: classProp = "",
|
|
56
|
+
...restProps
|
|
57
|
+
}: Props = $props();
|
|
58
|
+
|
|
59
|
+
const reduceMotion = prefersReducedMotion();
|
|
60
|
+
|
|
61
|
+
const effectiveAnimation = $derived(reduceMotion.current ? "none" : animation);
|
|
62
|
+
|
|
63
|
+
const baseClass = $derived(
|
|
64
|
+
twMerge(
|
|
65
|
+
"block bg-neutral-200 dark:bg-neutral-700",
|
|
66
|
+
effectiveAnimation === "shimmer" && "stuic-skeleton-shimmer",
|
|
67
|
+
effectiveAnimation === "pulse" && "stuic-skeleton-pulse",
|
|
68
|
+
variant === "circle" && "stuic-skeleton-circle",
|
|
69
|
+
rounded === true && variant !== "circle" && "rounded",
|
|
70
|
+
classProp
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const baseStyle = $derived.by(() => {
|
|
75
|
+
const styles: string[] = [];
|
|
76
|
+
if (duration) styles.push(`--skeleton-duration: ${duration}`);
|
|
77
|
+
if (variant === "circle" && size) {
|
|
78
|
+
styles.push(`width: ${size}`, `height: ${size}`);
|
|
79
|
+
} else {
|
|
80
|
+
if (width) styles.push(`width: ${width}`);
|
|
81
|
+
if (height) styles.push(`height: ${height}`);
|
|
82
|
+
}
|
|
83
|
+
if (typeof rounded === "string") {
|
|
84
|
+
styles.push(`border-radius: ${rounded}`);
|
|
85
|
+
}
|
|
86
|
+
return styles.join("; ");
|
|
87
|
+
});
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
{#if variant === "text" && lines > 1}
|
|
91
|
+
<div
|
|
92
|
+
bind:this={el}
|
|
93
|
+
role="status"
|
|
94
|
+
aria-busy="true"
|
|
95
|
+
aria-label={ariaLabel}
|
|
96
|
+
class="stuic-skeleton-text-container"
|
|
97
|
+
style:gap
|
|
98
|
+
{...restProps}
|
|
99
|
+
>
|
|
100
|
+
{#each Array(lines) as _, i}
|
|
101
|
+
{@const isLast = i === lines - 1}
|
|
102
|
+
<div
|
|
103
|
+
class={baseClass}
|
|
104
|
+
style="{baseStyle}; width: {isLast
|
|
105
|
+
? lastLineWidth
|
|
106
|
+
: width || '100%'}; height: {height || '1rem'}"
|
|
107
|
+
></div>
|
|
108
|
+
{/each}
|
|
109
|
+
{#if ariaLabel}
|
|
110
|
+
<span class="sr-only">{ariaLabel}</span>
|
|
111
|
+
{/if}
|
|
112
|
+
</div>
|
|
113
|
+
{:else}
|
|
114
|
+
<div
|
|
115
|
+
bind:this={el}
|
|
116
|
+
role="status"
|
|
117
|
+
aria-busy="true"
|
|
118
|
+
aria-label={ariaLabel}
|
|
119
|
+
class={baseClass}
|
|
120
|
+
style={baseStyle}
|
|
121
|
+
{...restProps}
|
|
122
|
+
>
|
|
123
|
+
{#if ariaLabel}
|
|
124
|
+
<span class="sr-only">{ariaLabel}</span>
|
|
125
|
+
{/if}
|
|
126
|
+
</div>
|
|
127
|
+
{/if}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "class"> {
|
|
3
|
+
/** Shape variant */
|
|
4
|
+
variant?: "text" | "circle" | "rectangle";
|
|
5
|
+
/** Width (e.g., "100%", "200px") */
|
|
6
|
+
width?: string;
|
|
7
|
+
/** Height (e.g., "1rem", "40px") */
|
|
8
|
+
height?: string;
|
|
9
|
+
/** Shorthand for circle size (sets both width & height) */
|
|
10
|
+
size?: string;
|
|
11
|
+
/** Number of text lines (for text variant) */
|
|
12
|
+
lines?: number;
|
|
13
|
+
/** Gap between lines (for text variant) */
|
|
14
|
+
gap?: string;
|
|
15
|
+
/** Last line width (for text variant) */
|
|
16
|
+
lastLineWidth?: string;
|
|
17
|
+
/** Animation style */
|
|
18
|
+
animation?: "shimmer" | "pulse" | "none";
|
|
19
|
+
/** Animation duration */
|
|
20
|
+
duration?: string;
|
|
21
|
+
/** Border radius (boolean for default, string for custom) */
|
|
22
|
+
rounded?: boolean | string;
|
|
23
|
+
/** Accessibility label */
|
|
24
|
+
ariaLabel?: string;
|
|
25
|
+
/** Bindable element reference */
|
|
26
|
+
el?: HTMLDivElement;
|
|
27
|
+
/** CSS class */
|
|
28
|
+
class?: string | string[];
|
|
29
|
+
}
|
|
30
|
+
import "./index.css";
|
|
31
|
+
declare const Skeleton: import("svelte").Component<Props, {}, "el">;
|
|
32
|
+
type Skeleton = ReturnType<typeof Skeleton>;
|
|
33
|
+
export default Skeleton;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* Define CSS custom properties for use in gradients */
|
|
2
|
+
:root {
|
|
3
|
+
--skeleton-base: #e5e5e5;
|
|
4
|
+
--skeleton-highlight: #f5f5f5;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.dark {
|
|
8
|
+
--skeleton-base: #404040;
|
|
9
|
+
--skeleton-highlight: #525252;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.stuic-skeleton-circle {
|
|
13
|
+
border-radius: 50%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.stuic-skeleton-text-container {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Shimmer animation */
|
|
22
|
+
@keyframes skeleton-shimmer {
|
|
23
|
+
0% {
|
|
24
|
+
background-position: -200% 0;
|
|
25
|
+
}
|
|
26
|
+
100% {
|
|
27
|
+
background-position: 200% 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.stuic-skeleton-shimmer {
|
|
32
|
+
background: linear-gradient(
|
|
33
|
+
90deg,
|
|
34
|
+
var(--skeleton-base) 25%,
|
|
35
|
+
var(--skeleton-highlight) 50%,
|
|
36
|
+
var(--skeleton-base) 75%
|
|
37
|
+
);
|
|
38
|
+
background-size: 200% 100%;
|
|
39
|
+
animation: skeleton-shimmer var(--skeleton-duration, 1.5s) ease-in-out infinite;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Pulse animation */
|
|
43
|
+
@keyframes skeleton-pulse {
|
|
44
|
+
0%, 100% {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
}
|
|
47
|
+
50% {
|
|
48
|
+
opacity: 0.4;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.stuic-skeleton-pulse {
|
|
53
|
+
animation: skeleton-pulse var(--skeleton-duration, 1.5s) ease-in-out infinite;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Reduced motion */
|
|
57
|
+
@media (prefers-reduced-motion: reduce) {
|
|
58
|
+
.stuic-skeleton-shimmer,
|
|
59
|
+
.stuic-skeleton-pulse {
|
|
60
|
+
animation: none;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Skeleton, type Props as SkeletonProps } from "./Skeleton.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Skeleton } from "./Skeleton.svelte";
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./components/Modal/index.js";
|
|
|
40
40
|
export * from "./components/ModalDialog/index.js";
|
|
41
41
|
export * from "./components/Notifications/index.js";
|
|
42
42
|
export * from "./components/Progress/index.js";
|
|
43
|
+
export * from "./components/Skeleton/index.js";
|
|
43
44
|
export * from "./components/SlidingPanels/index.js";
|
|
44
45
|
export * from "./components/Spinner/index.js";
|
|
45
46
|
export * from "./components/Switch/index.js";
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ export * from "./components/Modal/index.js";
|
|
|
41
41
|
export * from "./components/ModalDialog/index.js";
|
|
42
42
|
export * from "./components/Notifications/index.js";
|
|
43
43
|
export * from "./components/Progress/index.js";
|
|
44
|
+
export * from "./components/Skeleton/index.js";
|
|
44
45
|
export * from "./components/SlidingPanels/index.js";
|
|
45
46
|
export * from "./components/Spinner/index.js";
|
|
46
47
|
export * from "./components/Switch/index.js";
|