@xsolla/xui-avatar 0.150.0 → 0.151.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 (2) hide show
  1. package/README.md +102 -197
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,297 +1,202 @@
1
1
  # Avatar
2
2
 
3
- A cross-platform React avatar component that displays user images, icons, or text initials. Supports badges for notifications and can be grouped together.
3
+ A cross-platform React avatar component that displays a user image, icon, or text initials. Supports notification badges and grouping via `AvatarGroup`.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @xsolla/xui-avatar
9
- # or
10
- yarn add @xsolla/xui-avatar
11
9
  ```
12
10
 
13
- ## Demo
11
+ ## Imports
14
12
 
15
- ### Basic Avatar
13
+ ```tsx
14
+ import { Avatar, AvatarGroup, type AvatarGroupItem, type AvatarBackgroundMode } from '@xsolla/xui-avatar';
15
+ ```
16
+
17
+ ## Quick start
16
18
 
17
19
  ```tsx
18
20
  import * as React from 'react';
19
21
  import { Avatar } from '@xsolla/xui-avatar';
20
22
 
21
- export default function BasicAvatar() {
22
- return (
23
- <div style={{ display: 'flex', gap: 16 }}>
24
- <Avatar src="https://example.com/user.jpg" />
25
- <Avatar text="JD" />
26
- <Avatar /> {/* Default user icon */}
27
- </div>
28
- );
23
+ export default function QuickStart() {
24
+ return <Avatar text="JD" aria-label="John Doe" />;
29
25
  }
30
26
  ```
31
27
 
32
- ### Avatar Sizes
28
+ ## API Reference
33
29
 
34
- ```tsx
35
- import * as React from 'react';
36
- import { Avatar } from '@xsolla/xui-avatar';
30
+ ### `<Avatar>`
37
31
 
38
- export default function AvatarSizes() {
39
- return (
40
- <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
41
- <Avatar size="xs" text="XS" />
42
- <Avatar size="sm" text="S" />
43
- <Avatar size="md" text="M" />
44
- <Avatar size="lg" text="L" />
45
- <Avatar size="xl" text="XL" />
46
- </div>
47
- );
32
+ | Prop | Type | Default | Description |
33
+ | --- | --- | --- | --- |
34
+ | `src` | `string` | | Image source URL. |
35
+ | `icon` | `ReactNode` | — | Icon displayed when no `src` is supplied. |
36
+ | `text` | `string` | — | Text/initials displayed when no `src` or `icon` is supplied. |
37
+ | `size` | `"xl" \| "lg" \| "md" \| "sm" \| "xs" \| "xxs"` | `"xl"` | Avatar size. |
38
+ | `square` | `boolean` | `false` | Square (small radius) instead of circular. |
39
+ | `tone` | `"mono" \| "brand"` | `"mono"` | Visual tone. |
40
+ | `badge` | `boolean` | `false` | Show a notification badge. |
41
+ | `badgeCount` | `ReactNode` | — | Numeric or text content rendered inside the badge. |
42
+ | `badgeIcon` | `ReactNode` | — | Icon rendered inside the badge. |
43
+ | `badgeTone` | `"primary" \| "secondary" \| "brand" \| "brandExtra" \| "success" \| "warning" \| "alert" \| "neutral"` | `"alert"` | Badge colour tone. |
44
+ | `aria-label` | `string` | — | Accessible label. Recommended for screen readers. |
45
+ | `alt` | `string` | — | Alt text for the image (falls back to `aria-label`). |
46
+ | `onClick` | `() => void` | — | Click handler. When provided, the avatar becomes a focusable button. |
47
+
48
+ Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
49
+
50
+ `backgroundColor` and `disableHover` exist on the source type but are reserved for internal use by `AvatarGroup` (`@internal`); avoid setting them directly.
51
+
52
+ ### `<AvatarGroup>`
53
+
54
+ | Prop | Type | Default | Description |
55
+ | --- | --- | --- | --- |
56
+ | `list` | `AvatarGroupItem[]` | — | **Required.** Avatars to display. |
57
+ | `size` | `"xxs" \| "xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"sm"` | Size applied to every avatar. |
58
+ | `maxVisible` | `number` | `6` | Maximum slots rendered, including the "+N" overflow counter. |
59
+ | `avatarBackgroundMode` | `"mixed" \| "brand" \| "brandExtra" \| "success" \| "warning" \| "alert" \| "neutral" \| ((theme) => string)` | `"mixed"` | Background colour mode for non-image avatars. |
60
+ | `aria-label` | `string` | auto | Accessible label for the group. Defaults to "X users" / "N of M users". |
61
+
62
+ Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
63
+
64
+ ### `AvatarGroupItem`
65
+
66
+ ```typescript
67
+ interface AvatarGroupItem {
68
+ src?: string;
69
+ initials?: string;
70
+ tooltip?: string;
71
+ badge?: boolean;
72
+ badgeCount?: React.ReactNode;
73
+ badgeIcon?: React.ReactNode;
74
+ badgeTone?: AvatarProps["badgeTone"];
48
75
  }
49
76
  ```
50
77
 
51
- ### Avatar with Badge
78
+ ## Examples
79
+
80
+ ### Sizes
52
81
 
53
82
  ```tsx
54
83
  import * as React from 'react';
55
84
  import { Avatar } from '@xsolla/xui-avatar';
56
85
 
57
- export default function AvatarWithBadge() {
86
+ export default function AvatarSizes() {
58
87
  return (
59
- <div style={{ display: 'flex', gap: 24 }}>
60
- <Avatar src="https://example.com/user.jpg" badge />
61
- <Avatar src="https://example.com/user.jpg" badge badgeCount={5} />
62
- <Avatar src="https://example.com/user.jpg" badge badgeCount={99} badgeTone="alert" />
88
+ <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
89
+ <Avatar size="xxs" text="A" />
90
+ <Avatar size="xs" text="A" />
91
+ <Avatar size="sm" text="A" />
92
+ <Avatar size="md" text="A" />
93
+ <Avatar size="lg" text="A" />
94
+ <Avatar size="xl" text="A" />
63
95
  </div>
64
96
  );
65
97
  }
66
98
  ```
67
99
 
68
- ### Square Avatar
100
+ ### Tones
69
101
 
70
102
  ```tsx
71
103
  import * as React from 'react';
72
104
  import { Avatar } from '@xsolla/xui-avatar';
73
105
 
74
- export default function SquareAvatar() {
106
+ export default function AvatarTones() {
75
107
  return (
76
108
  <div style={{ display: 'flex', gap: 16 }}>
77
- <Avatar src="https://example.com/user.jpg" />
78
- <Avatar src="https://example.com/user.jpg" square />
109
+ <Avatar tone="mono" text="JD" />
110
+ <Avatar tone="brand" text="JD" />
79
111
  </div>
80
112
  );
81
113
  }
82
114
  ```
83
115
 
84
- ## Anatomy
85
-
86
- Import the component and use it directly:
87
-
88
- ```jsx
89
- import { Avatar } from '@xsolla/xui-avatar';
90
-
91
- <Avatar
92
- src="image-url" // Image source URL
93
- text="AB" // Text/initials when no image
94
- icon={<CustomIcon />} // Custom icon when no image
95
- size="md" // Size variant
96
- square={false} // Square vs circular
97
- badge={false} // Show notification badge
98
- badgeCount={5} // Badge count
99
- badgeTone="brand" // Badge color tone
100
- tone="mono" // Visual tone ('mono' | 'brand')
101
- onClick={handleClick} // Click handler
102
- />
103
- ```
104
-
105
- ## Examples
106
-
107
- ### Avatar Tones
108
-
109
- Use the `tone` prop to switch between the default `mono` background and the `brand` background.
116
+ ### With badge
110
117
 
111
118
  ```tsx
112
119
  import * as React from 'react';
113
120
  import { Avatar } from '@xsolla/xui-avatar';
121
+ import { Bell } from '@xsolla/xui-icons-base';
114
122
 
115
- export default function AvatarTones() {
123
+ export default function AvatarWithBadge() {
116
124
  return (
117
- <div style={{ display: 'flex', gap: 16 }}>
118
- <Avatar tone="mono" text="JD" />
119
- <Avatar tone="brand" text="JD" />
125
+ <div style={{ display: 'flex', gap: 24 }}>
126
+ <Avatar text="JD" badge />
127
+ <Avatar text="JD" badge badgeCount={5} />
128
+ <Avatar text="JD" badge badgeIcon={<Bell />} badgeTone="brand" />
120
129
  </div>
121
130
  );
122
131
  }
123
132
  ```
124
133
 
125
- ### Avatar with Custom Icon
134
+ ### Square
126
135
 
127
136
  ```tsx
128
137
  import * as React from 'react';
129
138
  import { Avatar } from '@xsolla/xui-avatar';
130
- import { Building2, Briefcase, Star } from '@xsolla/xui-icons-base';
131
139
 
132
- export default function AvatarWithIcon() {
133
- return (
134
- <div style={{ display: 'flex', gap: 16 }}>
135
- <Avatar icon={<Building2 />} />
136
- <Avatar icon={<Briefcase />} tone="brand" />
137
- <Avatar icon={<Star />} />
138
- </div>
139
- );
140
+ export default function SquareAvatar() {
141
+ return <Avatar text="AB" square size="lg" />;
140
142
  }
141
143
  ```
142
144
 
143
- ### Avatar with Stroke
145
+ ### Custom icon
144
146
 
145
147
  ```tsx
146
148
  import * as React from 'react';
147
149
  import { Avatar } from '@xsolla/xui-avatar';
150
+ import { Briefcase } from '@xsolla/xui-icons-base';
148
151
 
149
- export default function AvatarWithStroke() {
150
- return (
151
- <Avatar
152
- src="https://example.com/user.jpg"
153
- stroke
154
- size="lg"
155
- />
156
- );
152
+ export default function AvatarWithIcon() {
153
+ return <Avatar icon={<Briefcase />} tone="brand" aria-label="Work account" />;
157
154
  }
158
155
  ```
159
156
 
160
- ### Clickable Avatar
157
+ ### Clickable
161
158
 
162
159
  ```tsx
163
160
  import * as React from 'react';
164
161
  import { Avatar } from '@xsolla/xui-avatar';
165
162
 
166
163
  export default function ClickableAvatar() {
164
+ const [count, setCount] = React.useState(0);
167
165
  return (
168
166
  <Avatar
169
167
  text="JD"
170
168
  size="lg"
171
- onClick={() => alert('Avatar clicked!')}
172
- aria-label="View John Doe's profile"
169
+ onClick={() => setCount((c) => c + 1)}
170
+ aria-label={`Open profile (clicked ${count} times)`}
173
171
  />
174
172
  );
175
173
  }
176
174
  ```
177
175
 
178
- ### Avatar Group
176
+ ### Avatar group
179
177
 
180
178
  ```tsx
181
179
  import * as React from 'react';
182
- import { AvatarGroup } from '@xsolla/xui-avatar';
180
+ import { AvatarGroup, type AvatarGroupItem } from '@xsolla/xui-avatar';
183
181
 
184
182
  export default function AvatarGroupExample() {
185
- const users = [
186
- { src: 'https://example.com/user1.jpg' },
187
- { src: 'https://example.com/user2.jpg' },
188
- { initials: 'JD' },
189
- { initials: 'AB' },
190
- { initials: 'CD' },
191
- { initials: 'EF' },
192
- { initials: 'GH' },
183
+ const users: AvatarGroupItem[] = [
184
+ { initials: 'JD', tooltip: 'John Doe' },
185
+ { initials: 'AB', tooltip: 'Anna Brown' },
186
+ { initials: 'CD', tooltip: 'Carl Davis' },
187
+ { initials: 'EF', tooltip: 'Emma Frost' },
188
+ { initials: 'GH', tooltip: 'Grace Hill' },
189
+ { initials: 'IJ', tooltip: 'Ivan Jones' },
190
+ { initials: 'KL', tooltip: 'Kim Lee' },
193
191
  ];
194
192
 
195
- return (
196
- <AvatarGroup
197
- list={users}
198
- maxVisible={5}
199
- size="md"
200
- />
201
- );
202
- }
203
- ```
204
-
205
- ### Badge Tones
206
-
207
- ```tsx
208
- import * as React from 'react';
209
- import { Avatar } from '@xsolla/xui-avatar';
210
-
211
- export default function BadgeTones() {
212
- return (
213
- <div style={{ display: 'flex', gap: 24 }}>
214
- <Avatar text="A" badge badgeCount={3} badgeTone="brand" />
215
- <Avatar text="B" badge badgeCount={3} badgeTone="success" />
216
- <Avatar text="C" badge badgeCount={3} badgeTone="warning" />
217
- <Avatar text="D" badge badgeCount={3} badgeTone="alert" />
218
- </div>
219
- );
193
+ return <AvatarGroup list={users} maxVisible={5} size="md" />;
220
194
  }
221
195
  ```
222
196
 
223
- ## API Reference
224
-
225
- ### Avatar
226
-
227
- An avatar component for displaying user representation.
228
-
229
- **Avatar Props:**
230
-
231
- | Prop | Type | Default | Description |
232
- | :--- | :--- | :------ | :---------- |
233
- | src | `string` | - | Image source URL. |
234
- | icon | `ReactNode` | - | Icon to display when no image. |
235
- | text | `string` | - | Text/initials when no image or icon. |
236
- | size | `"xl" \| "lg" \| "md" \| "sm" \| "xs"` | `"md"` | Size of the avatar. |
237
- | square | `boolean` | `false` | Square with border radius vs circular. |
238
- | badge | `boolean` | `false` | Show notification badge. |
239
- | badgeCount | `ReactNode` | - | Badge count or content. |
240
- | badgeTone | `"primary" \| "secondary" \| "brand" \| "brandExtra" \| "success" \| "warning" \| "alert" \| "neutral"` | `"alert"` | Badge color tone. |
241
- | tone | `"mono" \| "brand"` | `"mono"` | Visual tone. |
242
- | disableHover | `boolean` | `true` | Disable hover effect. |
243
- | aria-label | `string` | - | Accessible label. |
244
- | alt | `string` | - | Alt text for image. |
245
- | onClick | `() => void` | - | Click handler. |
246
-
247
- ---
248
-
249
- ### AvatarGroup
250
-
251
- A component for displaying multiple avatars with overlap.
252
-
253
- **AvatarGroup Props:**
254
-
255
- | Prop | Type | Default | Description |
256
- | :--- | :--- | :------ | :---------- |
257
- | list | `AvatarGroupItem[]` | - | **Required.** Array of avatar items. |
258
- | size | `"sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of avatars. |
259
- | maxVisible | `number` | `6` | Max avatars before "+N" counter. |
260
- | stroke | `boolean` | `true` | Show borders on avatars. |
261
- | avatarBackgroundMode | `"mixed" \| ToneString \| Function` | `"mixed"` | Background color mode. |
262
- | aria-label | `string` | - | Accessible label for the group. |
263
-
264
- **AvatarGroupItem:**
265
-
266
- ```typescript
267
- interface AvatarGroupItem {
268
- src?: string; // Image URL
269
- initials?: string; // Text initials
270
- onClick?: () => void; // Click handler
271
- tooltip?: string; // Tooltip on hover
272
- }
273
- ```
274
-
275
- ## Theming
276
-
277
- Avatar uses the design system theme for colors:
278
-
279
- ```typescript
280
- // Colors accessed via theme
281
- theme.colors.background.secondary // Default avatar background
282
- theme.colors.background.brand.primary // Brand background (e.g. #80EAFF in dark)
283
- theme.colors.content.primary // Text/icon color
284
- theme.colors.border.primary // Stroke color
285
- ```
286
-
287
- ### Square Border Radius
288
-
289
- Square avatars use `radius.avatarLarge` (8px) for xl–sm sizes and `radius.avatarSmall` (4px) for xs.
290
-
291
197
  ## Accessibility
292
198
 
293
- - Supports `aria-label` for screen readers
294
- - `alt` attribute for images
295
- - Keyboard accessible when clickable (Enter/Space)
296
- - Focus indicator follows WCAG guidelines
297
- - Badge count announced to assistive technology
199
+ - Pass `aria-label` so screen readers can identify the avatar; `alt` falls back to it for images.
200
+ - When `onClick` is set the root receives `role="button"`, `tabIndex={0}`, and Enter/Space activation.
201
+ - `AvatarGroup` is a `role="group"` with an auto-generated label such as "5 of 12 users".
202
+ - The "+N" overflow counter announces "N more user(s)" via `aria-label`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-avatar",
3
- "version": "0.150.0",
3
+ "version": "0.151.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -10,11 +10,11 @@
10
10
  "build:native": "PLATFORM=native tsup"
11
11
  },
12
12
  "dependencies": {
13
- "@xsolla/xui-badge": "0.150.0",
14
- "@xsolla/xui-core": "0.150.0",
15
- "@xsolla/xui-icons-base": "0.150.0",
16
- "@xsolla/xui-primitives-core": "0.150.0",
17
- "@xsolla/xui-tooltip": "0.150.0"
13
+ "@xsolla/xui-badge": "0.151.0",
14
+ "@xsolla/xui-core": "0.151.0",
15
+ "@xsolla/xui-icons-base": "0.151.0",
16
+ "@xsolla/xui-primitives-core": "0.151.0",
17
+ "@xsolla/xui-tooltip": "0.151.0"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": ">=16.8.0",