saha-ui 1.14.0 → 1.15.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 (33) hide show
  1. package/dist/components/Skeleton/Skeleton.styles.d.ts +18 -3
  2. package/dist/components/Skeleton/Skeleton.styles.d.ts.map +1 -1
  3. package/dist/components/Skeleton/Skeleton.styles.js +79 -41
  4. package/dist/components/Skeleton/Skeleton.types.d.ts +196 -6
  5. package/dist/components/Skeleton/Skeleton.types.d.ts.map +1 -1
  6. package/dist/components/Skeleton/index.d.ts +41 -7
  7. package/dist/components/Skeleton/index.d.ts.map +1 -1
  8. package/dist/components/Skeleton/index.js +60 -49
  9. package/dist/components/Skeleton/presets/SkeletonAvatar.d.ts +33 -0
  10. package/dist/components/Skeleton/presets/SkeletonAvatar.d.ts.map +1 -0
  11. package/dist/components/Skeleton/presets/SkeletonAvatar.js +97 -0
  12. package/dist/components/Skeleton/presets/SkeletonCard.d.ts +29 -0
  13. package/dist/components/Skeleton/presets/SkeletonCard.d.ts.map +1 -0
  14. package/dist/components/Skeleton/presets/SkeletonCard.js +80 -0
  15. package/dist/components/Skeleton/presets/SkeletonForm.d.ts +29 -0
  16. package/dist/components/Skeleton/presets/SkeletonForm.d.ts.map +1 -0
  17. package/dist/components/Skeleton/presets/SkeletonForm.js +80 -0
  18. package/dist/components/Skeleton/presets/SkeletonList.d.ts +35 -0
  19. package/dist/components/Skeleton/presets/SkeletonList.d.ts.map +1 -0
  20. package/dist/components/Skeleton/presets/SkeletonList.js +92 -0
  21. package/dist/components/Skeleton/presets/SkeletonTable.d.ts +29 -0
  22. package/dist/components/Skeleton/presets/SkeletonTable.d.ts.map +1 -0
  23. package/dist/components/Skeleton/presets/SkeletonTable.js +73 -0
  24. package/dist/components/Skeleton/presets/SkeletonText.d.ts +29 -0
  25. package/dist/components/Skeleton/presets/SkeletonText.d.ts.map +1 -0
  26. package/dist/components/Skeleton/presets/SkeletonText.js +42 -0
  27. package/dist/components/Skeleton/presets/index.d.ts +14 -0
  28. package/dist/components/Skeleton/presets/index.d.ts.map +1 -0
  29. package/dist/components/Skeleton/presets/index.js +14 -0
  30. package/dist/index.d.ts +4 -2
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +552 -539
  33. package/package.json +1 -1
@@ -1,6 +1,21 @@
1
+ /**
2
+ * Skeleton variant styles using CVA
3
+ *
4
+ * Why we use skeleton loaders:
5
+ * 1. Improve perceived performance - users see immediate feedback
6
+ * 2. Reduce layout shift - maintain space before content loads
7
+ * 3. Better UX - animated placeholders feel more responsive than blank screens
8
+ * 4. Communicate loading state - users understand content is coming
9
+ */
1
10
  export declare const skeletonVariants: (props?: ({
2
- variant?: "default" | "gradient" | "glass" | "pulse" | "shimmer" | "wave" | null | undefined;
3
- shape?: "text" | "circle" | "rounded" | "rectangle" | null | undefined;
4
- speed?: "normal" | "slow" | "fast" | null | undefined;
11
+ variant?: "default" | "gradient" | "glass" | "pulse" | "shimmer" | "glow" | "wave" | null | undefined;
12
+ shape?: "input" | "button" | "text" | "circle" | "rounded" | "avatar" | "rectangle" | "card" | null | undefined;
13
+ speed?: "normal" | "slow" | "fast" | "ultra-fast" | null | undefined;
14
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
15
+ /**
16
+ * Container variant for skeleton groups
17
+ */
18
+ export declare const skeletonContainerVariants: (props?: ({
19
+ spacing?: "normal" | "loose" | "tight" | "relaxed" | null | undefined;
5
20
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
6
21
  //# sourceMappingURL=Skeleton.styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/Skeleton.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB;;;;8EA6F5B,CAAC"}
1
+ {"version":3,"file":"Skeleton.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/Skeleton.styles.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;;8EAyH5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB;;8EAerC,CAAC"}
@@ -4,86 +4,108 @@ const a = e(
4
4
  // Base styles
5
5
  "relative",
6
6
  "overflow-hidden",
7
- "bg-base-200/50",
8
- "dark:bg-base-content/10",
9
- "shadow-sm"
7
+ "bg-gradient-to-r",
8
+ "from-muted/60",
9
+ "via-muted/40",
10
+ "to-muted/60",
11
+ "dark:from-muted/20",
12
+ "dark:via-muted/10",
13
+ "dark:to-muted/20"
10
14
  ],
11
15
  {
12
16
  variants: {
13
17
  variant: {
14
- default: ["animate-pulse", "shadow-inner"],
15
- pulse: ["animate-pulse", "shadow-inner"],
18
+ // Simple pulse animation - best for subtle loading states
19
+ default: ["animate-pulse"],
20
+ // Pulse with enhanced rhythm - draws more attention
21
+ pulse: ["animate-[pulse_1.5s_cubic-bezier(0.4,0,0.6,1)_infinite]"],
22
+ // Wave effect with sweeping gradient - premium feel
16
23
  wave: [
17
- "shadow-md",
18
24
  "before:absolute",
19
25
  "before:inset-0",
20
26
  "before:-translate-x-full",
21
- "before:animate-[shimmer_2s_infinite]",
27
+ "before:animate-[shimmer_2s_ease-in-out_infinite]",
22
28
  "before:bg-gradient-to-r",
23
29
  "before:from-transparent",
24
- "before:via-primary/10",
25
- "before:to-transparent",
26
- "after:absolute",
27
- "after:inset-0",
28
- "after:bg-gradient-to-b",
29
- "after:from-transparent",
30
- "after:to-black/5"
30
+ "before:via-white/20",
31
+ "dark:before:via-white/10",
32
+ "before:to-transparent"
31
33
  ],
34
+ // Fast shimmer - energetic loading state
32
35
  shimmer: [
33
- "shadow-md",
34
36
  "before:absolute",
35
37
  "before:inset-0",
36
38
  "before:-translate-x-full",
37
- "before:animate-[shimmer_1.5s_infinite]",
39
+ "before:animate-[shimmer_1.5s_ease-in-out_infinite]",
38
40
  "before:bg-gradient-to-r",
39
41
  "before:from-transparent",
40
- "before:via-white/30",
41
- "dark:before:via-white/15",
42
+ "before:via-primary/20",
43
+ "dark:before:via-primary/15",
42
44
  "before:to-transparent",
43
- "before:shadow-[0_0_20px_10px_rgba(255,255,255,0.1)]"
45
+ "before:blur-sm"
44
46
  ],
47
+ // Gradient flow - smooth color transition
45
48
  gradient: [
46
49
  "bg-gradient-to-r",
47
- "from-base-200/50",
48
- "via-primary/10",
49
- "to-base-200/50",
50
- "dark:from-base-content/10",
51
- "dark:via-primary/5",
52
- "dark:to-base-content/10",
53
- "animate-pulse",
54
- "shadow-lg"
50
+ "from-muted/80",
51
+ "via-primary/20",
52
+ "to-muted/80",
53
+ "dark:from-muted/30",
54
+ "dark:via-primary/10",
55
+ "dark:to-muted/30",
56
+ "animate-[pulse_2s_ease-in-out_infinite]",
57
+ "bg-[length:200%_100%]"
55
58
  ],
59
+ // Glass morphism effect - modern and elegant
56
60
  glass: [
57
61
  "bg-white/5",
58
- "backdrop-blur-md",
62
+ "dark:bg-white/[0.02]",
63
+ "backdrop-blur-sm",
59
64
  "border",
60
65
  "border-white/10",
61
- "shadow-xl",
66
+ "dark:border-white/5",
62
67
  "before:absolute",
63
68
  "before:inset-0",
64
69
  "before:-translate-x-full",
65
- "before:animate-[shimmer_2s_infinite]",
70
+ "before:animate-[shimmer_2.5s_ease-in-out_infinite]",
66
71
  "before:bg-gradient-to-r",
67
72
  "before:from-transparent",
68
- "before:via-white/20",
69
- "before:to-transparent",
70
- "after:absolute",
71
- "after:inset-0",
72
- "after:bg-gradient-to-br",
73
- "after:from-white/5",
74
- "after:to-transparent"
73
+ "before:via-white/15",
74
+ "dark:before:via-white/8",
75
+ "before:to-transparent"
76
+ ],
77
+ // Glow effect - attention-grabbing
78
+ glow: [
79
+ "animate-[pulse_2s_ease-in-out_infinite]",
80
+ "shadow-lg",
81
+ "shadow-primary/10",
82
+ "dark:shadow-primary/5",
83
+ "before:absolute",
84
+ "before:inset-0",
85
+ "before:-translate-x-full",
86
+ "before:animate-[shimmer_2s_ease-in-out_infinite]",
87
+ "before:bg-gradient-to-r",
88
+ "before:from-transparent",
89
+ "before:via-primary/30",
90
+ "dark:before:via-primary/20",
91
+ "before:to-transparent"
75
92
  ]
76
93
  },
77
94
  shape: {
78
95
  rectangle: ["rounded-md"],
79
- circle: ["rounded-full"],
96
+ circle: ["rounded-full", "aspect-square"],
80
97
  rounded: ["rounded-lg"],
81
- text: ["rounded-sm"]
98
+ text: ["rounded-sm", "h-4"],
99
+ card: ["rounded-xl"],
100
+ button: ["rounded-lg", "h-10"],
101
+ input: ["rounded-md", "h-10"],
102
+ avatar: ["rounded-full", "aspect-square"]
82
103
  },
83
104
  speed: {
84
- slow: ["[animation-duration:2s]"],
105
+ slow: ["[animation-duration:3s]"],
85
106
  normal: [],
86
- fast: ["[animation-duration:0.8s]"]
107
+ fast: ["[animation-duration:1s]"],
108
+ "ultra-fast": ["[animation-duration:0.6s]"]
87
109
  }
88
110
  },
89
111
  defaultVariants: {
@@ -92,7 +114,23 @@ const a = e(
92
114
  speed: "normal"
93
115
  }
94
116
  }
117
+ ), t = e(
118
+ ["flex", "flex-col", "gap-3", "w-full"],
119
+ {
120
+ variants: {
121
+ spacing: {
122
+ tight: ["gap-1"],
123
+ normal: ["gap-3"],
124
+ loose: ["gap-4"],
125
+ relaxed: ["gap-6"]
126
+ }
127
+ },
128
+ defaultVariants: {
129
+ spacing: "normal"
130
+ }
131
+ }
95
132
  );
96
133
  export {
134
+ t as skeletonContainerVariants,
97
135
  a as skeletonVariants
98
136
  };
@@ -1,24 +1,67 @@
1
1
  import { default as React } from 'react';
2
2
  /**
3
3
  * Skeleton variant types
4
+ *
5
+ * - default: Simple pulse animation
6
+ * - pulse: Enhanced pulse with custom timing
7
+ * - wave: Sweeping wave effect from left to right
8
+ * - shimmer: Fast shimmer with primary color accent
9
+ * - gradient: Gradient flow animation
10
+ * - glass: Glass morphism effect with backdrop blur
11
+ * - glow: Glowing effect with shadow
4
12
  */
5
- export type SkeletonVariant = "default" | "pulse" | "wave" | "shimmer" | "gradient" | "glass";
13
+ export type SkeletonVariant = "default" | "pulse" | "wave" | "shimmer" | "gradient" | "glass" | "glow";
6
14
  /**
7
15
  * Skeleton shape types
16
+ *
17
+ * - rectangle: Standard rectangular shape with medium rounded corners
18
+ * - circle: Perfect circle shape (aspect-square)
19
+ * - rounded: Rounded rectangle with larger border radius
20
+ * - text: Small height for text line simulation
21
+ * - card: Card-like shape with extra large rounded corners
22
+ * - button: Button-sized shape
23
+ * - input: Input field sized shape
24
+ * - avatar: Circle avatar shape
8
25
  */
9
- export type SkeletonShape = "rectangle" | "circle" | "rounded" | "text";
26
+ export type SkeletonShape = "rectangle" | "circle" | "rounded" | "text" | "card" | "button" | "input" | "avatar";
10
27
  /**
11
28
  * Skeleton animation speed types
29
+ *
30
+ * - slow: 3s duration - subtle, calm loading
31
+ * - normal: 1.5s duration - balanced loading
32
+ * - fast: 1s duration - energetic loading
33
+ * - ultra-fast: 0.6s duration - very quick loading
12
34
  */
13
- export type SkeletonSpeed = "slow" | "normal" | "fast";
35
+ export type SkeletonSpeed = "slow" | "normal" | "fast" | "ultra-fast";
36
+ /**
37
+ * Skeleton container spacing types
38
+ */
39
+ export type SkeletonSpacing = "tight" | "normal" | "loose" | "relaxed";
14
40
  /**
15
41
  * Props for the Skeleton component
16
42
  *
17
43
  * @example
44
+ * Basic usage:
18
45
  * ```tsx
19
46
  * <Skeleton width="100%" height="20px" />
20
- * <Skeleton variant="pulse" shape="circle" width="48px" height="48px" />
21
- * <Skeleton variant="shimmer" count={3} />
47
+ * ```
48
+ *
49
+ * @example
50
+ * Avatar skeleton:
51
+ * ```tsx
52
+ * <Skeleton variant="shimmer" shape="circle" width="48px" height="48px" />
53
+ * ```
54
+ *
55
+ * @example
56
+ * Multiple text lines:
57
+ * ```tsx
58
+ * <Skeleton variant="pulse" shape="text" count={3} />
59
+ * ```
60
+ *
61
+ * @example
62
+ * Card skeleton:
63
+ * ```tsx
64
+ * <Skeleton variant="wave" shape="card" height="200px" />
22
65
  * ```
23
66
  */
24
67
  export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
@@ -34,16 +77,19 @@ export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>
34
77
  shape?: SkeletonShape;
35
78
  /**
36
79
  * Width of the skeleton (CSS value)
80
+ * Can be a number (converted to px) or a string with units
37
81
  * @default "100%"
38
82
  */
39
83
  width?: string | number;
40
84
  /**
41
85
  * Height of the skeleton (CSS value)
86
+ * Can be a number (converted to px) or a string with units
42
87
  * @default "20px"
43
88
  */
44
89
  height?: string | number;
45
90
  /**
46
91
  * Number of skeleton lines to render
92
+ * When count > 1, skeletons are stacked vertically with gap
47
93
  * @default 1
48
94
  */
49
95
  count?: number;
@@ -53,13 +99,157 @@ export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>
53
99
  */
54
100
  speed?: SkeletonSpeed;
55
101
  /**
56
- * Disable animation
102
+ * Disable animation completely
103
+ * Useful for reducing motion for accessibility
57
104
  * @default false
58
105
  */
59
106
  noAnimation?: boolean;
60
107
  /**
61
108
  * Custom border radius (only for rectangle shape)
109
+ * Overrides the default border radius for the shape
62
110
  */
63
111
  borderRadius?: string;
112
+ /**
113
+ * Spacing between multiple skeletons when count > 1
114
+ * @default "normal"
115
+ */
116
+ spacing?: SkeletonSpacing;
117
+ /**
118
+ * Custom CSS class names for additional styling
119
+ */
120
+ className?: string;
121
+ /**
122
+ * Custom inline styles
123
+ */
124
+ style?: React.CSSProperties;
125
+ }
126
+ /**
127
+ * Props for preset skeleton components
128
+ */
129
+ export interface SkeletonPresetProps extends Omit<SkeletonProps, "width" | "height" | "shape" | "count" | "spacing"> {
130
+ /**
131
+ * Custom CSS class names
132
+ */
133
+ className?: string;
134
+ }
135
+ /**
136
+ * Props for Card Skeleton component
137
+ */
138
+ export interface SkeletonCardProps extends SkeletonPresetProps {
139
+ /**
140
+ * Show image skeleton at the top
141
+ * @default true
142
+ */
143
+ showImage?: boolean;
144
+ /**
145
+ * Image height
146
+ * @default "200px"
147
+ */
148
+ imageHeight?: string;
149
+ /**
150
+ * Number of text lines
151
+ * @default 3
152
+ */
153
+ lines?: number;
154
+ /**
155
+ * Show action button skeleton
156
+ * @default true
157
+ */
158
+ showActions?: boolean;
159
+ }
160
+ /**
161
+ * Props for Avatar Skeleton component
162
+ */
163
+ export interface SkeletonAvatarProps extends SkeletonPresetProps {
164
+ /**
165
+ * Size of the avatar
166
+ * @default "md"
167
+ */
168
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
169
+ /**
170
+ * Show name text skeleton next to avatar
171
+ * @default false
172
+ */
173
+ showText?: boolean;
174
+ /**
175
+ * Number of text lines when showText is true
176
+ * @default 2
177
+ */
178
+ lines?: number;
179
+ }
180
+ /**
181
+ * Props for List Skeleton component
182
+ */
183
+ export interface SkeletonListProps extends SkeletonPresetProps {
184
+ /**
185
+ * Number of list items
186
+ * @default 3
187
+ */
188
+ items?: number;
189
+ /**
190
+ * Show avatar in each list item
191
+ * @default true
192
+ */
193
+ showAvatar?: boolean;
194
+ /**
195
+ * Avatar size
196
+ * @default "md"
197
+ */
198
+ avatarSize?: "sm" | "md" | "lg";
199
+ /**
200
+ * Number of text lines per item
201
+ * @default 2
202
+ */
203
+ lines?: number;
204
+ }
205
+ /**
206
+ * Props for Table Skeleton component
207
+ */
208
+ export interface SkeletonTableProps extends SkeletonPresetProps {
209
+ /**
210
+ * Number of rows
211
+ * @default 5
212
+ */
213
+ rows?: number;
214
+ /**
215
+ * Number of columns
216
+ * @default 4
217
+ */
218
+ columns?: number;
219
+ /**
220
+ * Show table header
221
+ * @default true
222
+ */
223
+ showHeader?: boolean;
224
+ }
225
+ /**
226
+ * Props for Form Skeleton component
227
+ */
228
+ export interface SkeletonFormProps extends SkeletonPresetProps {
229
+ /**
230
+ * Number of form fields
231
+ * @default 4
232
+ */
233
+ fields?: number;
234
+ /**
235
+ * Show submit button skeleton
236
+ * @default true
237
+ */
238
+ showButton?: boolean;
239
+ }
240
+ /**
241
+ * Props for Text Skeleton component
242
+ */
243
+ export interface SkeletonTextProps extends SkeletonPresetProps {
244
+ /**
245
+ * Number of text lines
246
+ * @default 3
247
+ */
248
+ lines?: number;
249
+ /**
250
+ * Last line width percentage
251
+ * @default 60
252
+ */
253
+ lastLineWidth?: number;
64
254
  }
65
255
  //# sourceMappingURL=Skeleton.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.types.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/Skeleton.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,MAAM,GACN,SAAS,GACT,UAAU,GACV,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
1
+ {"version":3,"file":"Skeleton.types.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/Skeleton.types.ts"],"names":[],"mappings":"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"}
@@ -6,19 +6,53 @@ import { SkeletonProps } from './Skeleton.types';
6
6
  * A flexible skeleton loader component for displaying placeholder content
7
7
  * while data is loading. Supports multiple variants, shapes, and animations.
8
8
  *
9
+ * Why use skeleton loaders?
10
+ * 1. **Perceived Performance**: Users see immediate visual feedback
11
+ * 2. **Reduced Layout Shift**: Maintains space before content loads (better CLS score)
12
+ * 3. **Better UX**: Animated placeholders feel more responsive than blank screens
13
+ * 4. **Loading Communication**: Users understand content is being fetched
14
+ * 5. **Progressive Loading**: Show structure before details
15
+ *
16
+ * How it works:
17
+ * - Uses CSS animations (pulse, shimmer, wave) to create loading effect
18
+ * - Pseudo-elements (::before) create animated gradient overlays
19
+ * - CVA (Class Variance Authority) manages variant combinations
20
+ * - Supports custom dimensions, shapes, and animation speeds
21
+ *
9
22
  * @example
23
+ * Basic usage:
10
24
  * ```tsx
11
- * // Basic skeleton
12
25
  * <Skeleton width="100%" height="20px" />
26
+ * ```
13
27
  *
14
- * // Circle skeleton (avatar)
15
- * <Skeleton variant="pulse" shape="circle" width="48px" height="48px" />
28
+ * @example
29
+ * Avatar skeleton:
30
+ * ```tsx
31
+ * <Skeleton variant="shimmer" shape="circle" width="48px" height="48px" />
32
+ * ```
16
33
  *
17
- * // Multiple skeleton lines
18
- * <Skeleton variant="shimmer" count={3} />
34
+ * @example
35
+ * Multiple text lines:
36
+ * ```tsx
37
+ * <Skeleton variant="pulse" shape="text" count={3} spacing="normal" />
38
+ * ```
19
39
  *
20
- * // Custom styling
21
- * <Skeleton variant="wave" width="200px" height="100px" className="mb-4" />
40
+ * @example
41
+ * Card skeleton with wave effect:
42
+ * ```tsx
43
+ * <Skeleton variant="wave" shape="card" height="200px" />
44
+ * ```
45
+ *
46
+ * @example
47
+ * Custom styling and no animation:
48
+ * ```tsx
49
+ * <Skeleton
50
+ * variant="gradient"
51
+ * width="200px"
52
+ * height="100px"
53
+ * className="mb-4"
54
+ * noAnimation={false}
55
+ * />
22
56
  * ```
23
57
  */
24
58
  export declare const Skeleton: React.ForwardRefExoticComponent<SkeletonProps & React.RefAttributes<HTMLDivElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,sFAuEpB,CAAC;AAIF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,QAAQ,sFA2FpB,CAAC;AAIF,eAAe,QAAQ,CAAC"}
@@ -1,64 +1,75 @@
1
- import { jsx as a } from "react/jsx-runtime";
2
- import k from "react";
3
- import { cn as u } from "../../lib/utils.js";
4
- import { skeletonVariants as v } from "./Skeleton.styles.js";
5
- const N = k.forwardRef(
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import V from "react";
3
+ import { cn as n } from "../../lib/utils.js";
4
+ import { skeletonVariants as v, skeletonContainerVariants as I } from "./Skeleton.styles.js";
5
+ const L = V.forwardRef(
6
6
  ({
7
- variant: o = "default",
8
- shape: t = "rectangle",
9
- width: l = "100%",
10
- height: r = "20px",
11
- count: f = 1,
12
- speed: s = "normal",
13
- noAnimation: e = !1,
14
- borderRadius: m,
15
- className: c,
16
- style: i,
17
- ...d
7
+ variant: m = "default",
8
+ shape: a = "rectangle",
9
+ width: e = "100%",
10
+ height: s = "20px",
11
+ count: l = 1,
12
+ speed: i = "normal",
13
+ spacing: x = "normal",
14
+ noAnimation: t = !1,
15
+ borderRadius: c,
16
+ className: d,
17
+ style: g,
18
+ ...f
18
19
  }, p) => {
19
- const x = typeof l == "number" ? `${l}px` : l, y = typeof r == "number" ? `${r}px` : r, n = {
20
- width: x,
21
- height: y,
22
- ...m && t === "rectangle" ? { borderRadius: m } : {},
23
- ...i
20
+ const o = typeof e == "number" ? `${e}px` : e, k = typeof s == "number" ? `${s}px` : s, u = {
21
+ width: o,
22
+ height: k,
23
+ ...c && a === "rectangle" ? { borderRadius: c } : {},
24
+ ...g
24
25
  };
25
- return f > 1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-2", ref: p, children: Array.from({ length: f }).map((S, g) => /* @__PURE__ */ a(
26
- "div",
27
- {
28
- className: u(
29
- v({
30
- variant: e ? void 0 : o,
31
- shape: t,
32
- speed: e ? void 0 : s
33
- }),
34
- e && "animate-none",
35
- c
36
- ),
37
- style: n,
38
- ...d
39
- },
40
- g
41
- )) }) : /* @__PURE__ */ a(
26
+ return l > 1 ? /* @__PURE__ */ r("div", { className: n(I({ spacing: x })), ref: p, children: Array.from({ length: l }).map((S, y) => {
27
+ const N = y === l - 1 && a === "text" && typeof e == "string" && e.includes("%") ? `${Math.max(40, parseInt(e) - 20)}%` : o;
28
+ return /* @__PURE__ */ r(
29
+ "div",
30
+ {
31
+ className: n(
32
+ v({
33
+ variant: t ? void 0 : m,
34
+ shape: a,
35
+ speed: t ? void 0 : i
36
+ }),
37
+ t && "animate-none",
38
+ d
39
+ ),
40
+ style: {
41
+ ...u,
42
+ width: N
43
+ },
44
+ ...f
45
+ },
46
+ y
47
+ );
48
+ }) }) : /* @__PURE__ */ r(
42
49
  "div",
43
50
  {
44
51
  ref: p,
45
- className: u(
52
+ className: n(
46
53
  v({
47
- variant: e ? void 0 : o,
48
- shape: t,
49
- speed: e ? void 0 : s
54
+ variant: t ? void 0 : m,
55
+ shape: a,
56
+ speed: t ? void 0 : i
50
57
  }),
51
- e && "animate-none",
52
- c
58
+ t && "animate-none",
59
+ d
53
60
  ),
54
- style: n,
55
- ...d
61
+ style: u,
62
+ "aria-busy": "true",
63
+ "aria-live": "polite",
64
+ role: "status",
65
+ ...f,
66
+ children: /* @__PURE__ */ r("span", { className: "sr-only", children: "Loading..." })
56
67
  }
57
68
  );
58
69
  }
59
70
  );
60
- N.displayName = "Skeleton";
71
+ L.displayName = "Skeleton";
61
72
  export {
62
- N as Skeleton,
63
- N as default
73
+ L as Skeleton,
74
+ L as default
64
75
  };