@marianmeres/stuic 3.93.0 → 3.94.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.
@@ -18,7 +18,9 @@ A flexible avatar component that displays user photos, initials, or icons with a
18
18
  | `bg` | `string` | - | Background color (Tailwind class). Ignored if `autoColor=true` |
19
19
  | `textColor` | `string` | - | Text color (Tailwind class). Ignored if `autoColor=true` |
20
20
  | `autoColor` | `boolean` | `false` | Generate deterministic pastel colors from hashSource/initials |
21
+ | `padding` | `string` | - | CSS padding around the visual circle. Outer keeps its size, inner circle shrinks (e.g. `"4px"`, `"0.25rem"`). Useful for larger tap targets. |
21
22
  | `class` | `string` | - | Additional CSS classes |
23
+ | `classInner` | `string` | - | Additional CSS classes for the inner element (only used when `padding` is set) |
22
24
  | `el` | `HTMLElement` | - | Bindable element reference |
23
25
 
24
26
  ## Usage
@@ -82,6 +84,18 @@ Generate deterministic pastel colors based on a hash source:
82
84
  <Avatar src="/photo.jpg" onclick={() => console.log("clicked")} />
83
85
  ```
84
86
 
87
+ ### Padded (larger tap target / visually smaller circle)
88
+
89
+ Use `padding` to keep the avatar's outer footprint (e.g. a 44px tap target) while shrinking the visible colored circle. The padded ring is transparent.
90
+
91
+ ```svelte
92
+ <!-- Outer stays at size="md" (2.75rem), circle shrinks by 4px on each side -->
93
+ <Avatar size="md" initials="AB" padding="4px" />
94
+ <Avatar size="md" autoColor initials="john@example.com" padding="0.25rem" onclick={() => {}} />
95
+ ```
96
+
97
+ When `padding` is set, `bg`, `textColor`, and `autoColor` automatically apply to the inner circle (not the outer element).
98
+
85
99
  ### Custom Colors
86
100
 
87
101
  ```svelte
@@ -107,6 +121,7 @@ Override globally in `:root` or locally via `style` prop:
107
121
  | `--stuic-avatar-fg` | `--stuic-color-muted-foreground` | Default text/icon color |
108
122
  | `--stuic-avatar-ring-width` | `3px` | Focus ring width (button mode) |
109
123
  | `--stuic-avatar-ring-color` | `--stuic-color-ring` | Focus ring color |
124
+ | `--stuic-avatar-padding` | - | Set by the `padding` prop; can also be driven directly via CSS |
110
125
 
111
126
  ### Size Tokens
112
127
 
@@ -148,6 +163,7 @@ The component uses data attributes for CSS styling:
148
163
  | ------------------ | ----------------------------- | ----------------------------------- |
149
164
  | `data-size` | `sm`, `md`, `lg`, `xl`, `2xl` | Size preset (only for preset sizes) |
150
165
  | `data-interactive` | `true` | Present when `onclick` is provided |
166
+ | `data-padded` | `""` | Present when `padding` is set |
151
167
 
152
168
  ## Theming
153
169
 
@@ -53,6 +53,19 @@ The component composes existing primitives and adds convention, not behavior. It
53
53
  />
54
54
  ```
55
55
 
56
+ ### Separate trigger vs header-tile avatar styling
57
+
58
+ `avatar` is the shared base; `avatarHeader` overrides keys on the header-tile Avatar only (shallow merge).
59
+
60
+ ```svelte
61
+ <UserAvatarMenu
62
+ identity={{ email: user.email }}
63
+ actions={{ onProfile: () => goto("/me"), onLogout: () => goto("/logout") }}
64
+ avatar={{ class: "size-8" }}
65
+ avatarHeader={{ class: "size-16", padding: "10px" }}
66
+ />
67
+ ```
68
+
56
69
  ## Props
57
70
 
58
71
  | Prop | Type | Default | Description |
@@ -65,7 +78,8 @@ The component composes existing primitives and adds convention, not behavior. It
65
78
  | `showRoles` | `boolean` | `false` | Render `identity.roles` under the email in the header tile. |
66
79
  | `extraItems` | `DropdownMenuItem[]` | — | Appended to the standard item set. |
67
80
  | `items` | `DropdownMenuItem[]` | — | Full override of the item list. Trigger + dropdown shell still render. |
68
- | `avatar` | `Partial<AvatarProps>` | — | Forwarded to the default trigger Avatar (and the header-tile Avatar). |
81
+ | `avatar` | `Partial<AvatarProps>` | — | Forwarded to BOTH the trigger Avatar and the header-tile Avatar. |
82
+ | `avatarHeader` | `Partial<AvatarProps>` | — | Overrides applied on top of `avatar` for the header-tile Avatar only. Shallow merge. |
69
83
  | `position` | `DropdownMenuPosition` | — | Forwarded to `DropdownMenu`. |
70
84
  | `offset` | `string` | — | Forwarded. |
71
85
  | `maxHeight` | `string` | — | Forwarded. |
@@ -116,9 +116,16 @@
116
116
  */
117
117
  items?: DropdownMenuItem[];
118
118
 
119
- /** Forwarded to the default `Avatar` trigger and header-tile avatar. */
119
+ /** Forwarded to BOTH the trigger `Avatar` and the header-tile `Avatar`. */
120
120
  avatar?: Partial<Omit<AvatarProps, "onclick" | "initials" | "src" | "el">>;
121
121
 
122
+ /**
123
+ * Overrides applied on top of `avatar` for the header-tile `Avatar` only
124
+ * (the larger avatar shown above the menu items inside the popup).
125
+ * Shallow-merged: keys present here win over `avatar`.
126
+ */
127
+ avatarHeader?: Partial<Omit<AvatarProps, "onclick" | "initials" | "src" | "el">>;
128
+
122
129
  /** Forwarded to `DropdownMenu`. */
123
130
  position?: DropdownMenuPosition;
124
131
  offset?: string;
@@ -181,6 +188,7 @@
181
188
  extraItems,
182
189
  items: itemsOverride,
183
190
  avatar: avatarOverrides,
191
+ avatarHeader: avatarHeaderOverrides,
184
192
  position,
185
193
  offset,
186
194
  maxHeight,
@@ -197,6 +205,11 @@
197
205
 
198
206
  const isAuthed = $derived(!!identity);
199
207
 
208
+ const avatarHeaderMerged = $derived({
209
+ ...(avatarOverrides ?? {}),
210
+ ...(avatarHeaderOverrides ?? {}),
211
+ });
212
+
200
213
  // Color-scheme config normalization
201
214
  const cs = $derived(
202
215
  typeof colorScheme === "object" && colorScheme !== null ? colorScheme : {}
@@ -345,7 +358,7 @@
345
358
  hashSource={identity.email}
346
359
  src={identity.src}
347
360
  onclick={actions.onProfile}
348
- {...avatarOverrides}
361
+ {...avatarHeaderMerged}
349
362
  />
350
363
  <div class={!unstyled ? "stuic-user-avatar-menu-header-email" : undefined}>
351
364
  {identity.name ?? identity.email}
@@ -97,8 +97,14 @@ export interface Props {
97
97
  * `showHeaderTile`, `showRoles`) is not.
98
98
  */
99
99
  items?: DropdownMenuItem[];
100
- /** Forwarded to the default `Avatar` trigger and header-tile avatar. */
100
+ /** Forwarded to BOTH the trigger `Avatar` and the header-tile `Avatar`. */
101
101
  avatar?: Partial<Omit<AvatarProps, "onclick" | "initials" | "src" | "el">>;
102
+ /**
103
+ * Overrides applied on top of `avatar` for the header-tile `Avatar` only
104
+ * (the larger avatar shown above the menu items inside the popup).
105
+ * Shallow-merged: keys present here win over `avatar`.
106
+ */
107
+ avatarHeader?: Partial<Omit<AvatarProps, "onclick" | "initials" | "src" | "el">>;
102
108
  /** Forwarded to `DropdownMenu`. */
103
109
  position?: DropdownMenuPosition;
104
110
  offset?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.93.0",
3
+ "version": "3.94.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && pnpm run prepack",