@marianmeres/stuic 2.53.0 → 2.54.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.
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
export type IconFn = (opts?: { size?: number; class?: string }) => string;
|
|
3
|
-
export type AvatarFallback =
|
|
3
|
+
export type AvatarFallback =
|
|
4
|
+
| "icon"
|
|
5
|
+
| "initials"
|
|
6
|
+
| { icon: IconFn }
|
|
7
|
+
| { initials: string };
|
|
4
8
|
|
|
5
9
|
export interface Props {
|
|
6
10
|
/** Photo URL - when provided, renders in photo mode */
|
|
@@ -9,6 +13,8 @@
|
|
|
9
13
|
alt?: string;
|
|
10
14
|
/** String to extract initials from. Supports: "AB", "John Doe", or "john.doe@example.com" */
|
|
11
15
|
initials?: string;
|
|
16
|
+
/** optional length */
|
|
17
|
+
initialsLength?: number;
|
|
12
18
|
/** Icon function to display - when provided alone, renders in icon mode */
|
|
13
19
|
icon?: IconFn;
|
|
14
20
|
/** Fallback when photo fails to load. Defaults to "icon" */
|
|
@@ -41,6 +47,7 @@
|
|
|
41
47
|
src,
|
|
42
48
|
alt,
|
|
43
49
|
initials: initialsProp,
|
|
50
|
+
initialsLength = 2,
|
|
44
51
|
icon,
|
|
45
52
|
fallback = "icon",
|
|
46
53
|
hashSource,
|
|
@@ -60,26 +67,14 @@
|
|
|
60
67
|
xl: { container: "size-16 text-lg", icon: 32 },
|
|
61
68
|
};
|
|
62
69
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// Reset image state when src changes
|
|
67
|
-
$effect(() => {
|
|
68
|
-
if (src) {
|
|
69
|
-
imageError = false;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Extract initials from string
|
|
74
|
-
let extractedInitials = $derived.by(() => {
|
|
75
|
-
let _input = (initialsProp || "").trim();
|
|
76
|
-
|
|
70
|
+
// Extract initials from input string (email, name, or raw initials)
|
|
71
|
+
function extractInitials(input: string, length: number): string {
|
|
72
|
+
let _input = (input || "").trim();
|
|
77
73
|
if (!_input) return "?";
|
|
78
74
|
|
|
79
|
-
//
|
|
75
|
+
// Email handling
|
|
80
76
|
if (_input.includes("@")) {
|
|
81
77
|
const username = _input.split("@")[0];
|
|
82
|
-
// Split by common separators (., _, -)
|
|
83
78
|
const parts = username.split(/[._+-]/).filter(Boolean);
|
|
84
79
|
if (parts.length > 1) {
|
|
85
80
|
_input = parts.map((p) => p.charAt(0)).join("");
|
|
@@ -87,8 +82,8 @@
|
|
|
87
82
|
_input = username;
|
|
88
83
|
}
|
|
89
84
|
}
|
|
90
|
-
//
|
|
91
|
-
else if (_input.length >
|
|
85
|
+
// Full name handling
|
|
86
|
+
else if (_input.length > length && /\s/.test(_input)) {
|
|
92
87
|
_input = _input
|
|
93
88
|
.split(/\s/)
|
|
94
89
|
.map((v) => v.trim())
|
|
@@ -97,10 +92,21 @@
|
|
|
97
92
|
.join("");
|
|
98
93
|
}
|
|
99
94
|
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
return _input.slice(0, length).toUpperCase();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Image loading state
|
|
99
|
+
let imageError = $state(false);
|
|
100
|
+
|
|
101
|
+
// Reset image state when src changes
|
|
102
|
+
$effect(() => {
|
|
103
|
+
if (src) {
|
|
104
|
+
imageError = false;
|
|
105
|
+
}
|
|
102
106
|
});
|
|
103
107
|
|
|
108
|
+
let extractedInitials = $derived(extractInitials(initialsProp || "", initialsLength));
|
|
109
|
+
|
|
104
110
|
// Determine the current render mode
|
|
105
111
|
let renderMode = $derived.by((): "photo" | "initials" | "icon" => {
|
|
106
112
|
// Photo mode (if src provided and no error)
|
|
@@ -121,28 +127,7 @@
|
|
|
121
127
|
// Get fallback initials (from fallback prop or initialsProp)
|
|
122
128
|
let fallbackInitials = $derived.by(() => {
|
|
123
129
|
if (typeof fallback === "object" && "initials" in fallback) {
|
|
124
|
-
|
|
125
|
-
if (!_input) return "?";
|
|
126
|
-
|
|
127
|
-
// Apply same extraction logic
|
|
128
|
-
let result = _input;
|
|
129
|
-
if (_input.includes("@")) {
|
|
130
|
-
const username = _input.split("@")[0];
|
|
131
|
-
const parts = username.split(/[._+-]/).filter(Boolean);
|
|
132
|
-
if (parts.length > 1) {
|
|
133
|
-
result = parts.map((p) => p.charAt(0)).join("");
|
|
134
|
-
} else {
|
|
135
|
-
result = username;
|
|
136
|
-
}
|
|
137
|
-
} else if (_input.length > 2 && /\s/.test(_input)) {
|
|
138
|
-
result = _input
|
|
139
|
-
.split(/\s/)
|
|
140
|
-
.map((v) => v.trim())
|
|
141
|
-
.filter(Boolean)
|
|
142
|
-
.map((v) => v.charAt(0))
|
|
143
|
-
.join("");
|
|
144
|
-
}
|
|
145
|
-
return result.slice(0, 2).toUpperCase();
|
|
130
|
+
return extractInitials(fallback.initials || "", initialsLength);
|
|
146
131
|
}
|
|
147
132
|
return extractedInitials;
|
|
148
133
|
});
|
|
@@ -207,12 +192,7 @@
|
|
|
207
192
|
{#if onclick}
|
|
208
193
|
<button bind:this={el} type="button" class={baseClass} {style} {onclick}>
|
|
209
194
|
{#if renderMode === "photo"}
|
|
210
|
-
<img
|
|
211
|
-
{src}
|
|
212
|
-
{alt}
|
|
213
|
-
class="size-full object-cover"
|
|
214
|
-
onerror={handleImageError}
|
|
215
|
-
/>
|
|
195
|
+
<img {src} {alt} class="size-full object-cover" onerror={handleImageError} />
|
|
216
196
|
{:else if renderMode === "initials"}
|
|
217
197
|
{fallbackInitials}
|
|
218
198
|
{:else}
|
|
@@ -222,12 +202,7 @@
|
|
|
222
202
|
{:else}
|
|
223
203
|
<div bind:this={el} class={baseClass} {style}>
|
|
224
204
|
{#if renderMode === "photo"}
|
|
225
|
-
<img
|
|
226
|
-
{src}
|
|
227
|
-
{alt}
|
|
228
|
-
class="size-full object-cover"
|
|
229
|
-
onerror={handleImageError}
|
|
230
|
-
/>
|
|
205
|
+
<img {src} {alt} class="size-full object-cover" onerror={handleImageError} />
|
|
231
206
|
{:else if renderMode === "initials"}
|
|
232
207
|
{fallbackInitials}
|
|
233
208
|
{:else}
|
|
@@ -14,6 +14,8 @@ export interface Props {
|
|
|
14
14
|
alt?: string;
|
|
15
15
|
/** String to extract initials from. Supports: "AB", "John Doe", or "john.doe@example.com" */
|
|
16
16
|
initials?: string;
|
|
17
|
+
/** optional length */
|
|
18
|
+
initialsLength?: number;
|
|
17
19
|
/** Icon function to display - when provided alone, renders in icon mode */
|
|
18
20
|
icon?: IconFn;
|
|
19
21
|
/** Fallback when photo fails to load. Defaults to "icon" */
|