@libs-ui/components-avatar 0.2.355-9 → 0.2.356-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/README.md +133 -188
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,128 +1,145 @@
|
|
|
1
|
-
# Avatar
|
|
1
|
+
# Avatar Component
|
|
2
|
+
|
|
3
|
+
> Version: `0.2.355-10`
|
|
4
|
+
>
|
|
5
|
+
> Component hiển thị avatar (ảnh đại diện) với khả năng fallback sang text/icon khi ảnh lỗi hoặc không có.
|
|
2
6
|
|
|
3
7
|
## Giới thiệu
|
|
4
8
|
|
|
5
|
-
`
|
|
9
|
+
`LibsUiComponentsAvatarComponent` là một standalone Angular component để hiển thị avatar (ảnh đại diện) của người dùng. Component hỗ trợ nhiều kích thước, hình dạng (circle/rectangle), và có cơ chế fallback thông minh khi ảnh lỗi.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
### Tính năng
|
|
8
12
|
|
|
9
|
-
- Hiển thị
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- Hỗ trợ
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
13
|
+
- ✅ Hiển thị ảnh avatar từ URL
|
|
14
|
+
- ✅ Fallback tự động sang text/icon khi ảnh lỗi
|
|
15
|
+
- ✅ Hỗ trợ nhiều kích thước: 16, 24, 32, 40, 48, 64px
|
|
16
|
+
- ✅ Hỗ trợ 2 hình dạng: circle (mặc định) và rectangle
|
|
17
|
+
- ✅ Tự động tạo màu nền dựa trên ID (hash color)
|
|
18
|
+
- ✅ Preview ảnh khi click (tùy chọn)
|
|
19
|
+
- ✅ OnPush Change Detection
|
|
20
|
+
- ✅ Angular Signals
|
|
16
21
|
|
|
17
|
-
##
|
|
22
|
+
## Lưu ý quan trọng (Important Notes)
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
> ⚠️ **Caveats**:
|
|
25
|
+
>
|
|
26
|
+
> - **Thứ tự Input quan trọng**: Nếu sử dụng `getLastTextAfterSpace`, phải truyền input này **TRƯỚC** `textAvatar` để logic transform hoạt động đúng.
|
|
27
|
+
> - **Error Handling Chain**: Component có chuỗi xử lý lỗi: `linkAvatar` → `linkAvatarError` → `textAvatar` + `idGenColor`. Nếu tất cả đều fail, sẽ hiển thị icon với text.
|
|
28
|
+
> - **Màu nền tự động**: Màu nền được tạo từ `idGenColor` thông qua hàm hash. Cùng ID sẽ luôn có cùng màu.
|
|
29
|
+
> - **Font size tự động**: Font size của text avatar được tính tự động dựa trên `size` (16/24 → 6, 32 → 4, 40 → 3, 64 → 1, default → 4).
|
|
30
|
+
> - **Preview Image**: Khi `clickPreviewImage = true`, click vào ảnh sẽ mở gallery viewer. Component tự quản lý lifecycle của gallery viewer.
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
- Tailwind CSS 3.3.0 trở lên
|
|
32
|
+
## Khi nào sử dụng
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
- Hiển thị ảnh đại diện người dùng trong danh sách, comment, profile
|
|
35
|
+
- Hiển thị avatar với fallback khi ảnh không tải được
|
|
36
|
+
- Cần hiển thị avatar với nhiều kích thước khác nhau
|
|
37
|
+
- Cần preview ảnh khi click vào avatar
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
## Cài đặt
|
|
27
40
|
|
|
28
41
|
```bash
|
|
29
42
|
npm install @libs-ui/components-avatar
|
|
30
43
|
```
|
|
31
44
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
yarn add @libs-ui/components-avatar
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Sử dụng
|
|
39
|
-
|
|
40
|
-
### Import component
|
|
45
|
+
## Import
|
|
41
46
|
|
|
42
47
|
```typescript
|
|
43
|
-
|
|
44
|
-
import { Component } from '@angular/core';
|
|
45
|
-
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
|
|
48
|
+
import { LibsUiComponentsAvatarComponent, TYPE_SHAPE_AVATAR, TYPE_SIZE_AVATAR_CONFIG, IAvatarConfig } from '@libs-ui/components-avatar';
|
|
46
49
|
|
|
47
50
|
@Component({
|
|
48
|
-
selector: 'app-example',
|
|
49
51
|
standalone: true,
|
|
50
52
|
imports: [LibsUiComponentsAvatarComponent],
|
|
51
|
-
|
|
52
|
-
<libs_ui-components-avatar
|
|
53
|
-
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
54
|
-
[textAvatar]="'Nguyễn Văn A'"
|
|
55
|
-
[idGenColor]="'user-123'"
|
|
56
|
-
[size]="40"></libs_ui-components-avatar>
|
|
57
|
-
`,
|
|
53
|
+
// ...
|
|
58
54
|
})
|
|
59
|
-
export class ExampleComponent {
|
|
60
|
-
// Component logic
|
|
61
|
-
}
|
|
62
55
|
```
|
|
63
56
|
|
|
64
|
-
|
|
57
|
+
## Cách sử dụng
|
|
65
58
|
|
|
66
|
-
|
|
67
|
-
// example.component.ts
|
|
68
|
-
import { Component } from '@angular/core';
|
|
69
|
-
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
|
|
59
|
+
### 1. Basic - Avatar với ảnh
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
templateUrl: './example.component.html',
|
|
76
|
-
})
|
|
77
|
-
export class ExampleComponent {
|
|
78
|
-
// Component logic
|
|
79
|
-
}
|
|
61
|
+
```html
|
|
62
|
+
<libs_ui-components-avatar
|
|
63
|
+
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
64
|
+
[size]="32" />
|
|
80
65
|
```
|
|
81
66
|
|
|
67
|
+
### 2. Avatar với fallback text
|
|
68
|
+
|
|
82
69
|
```html
|
|
83
|
-
<!-- example.component.html -->
|
|
84
70
|
<libs_ui-components-avatar
|
|
85
71
|
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
86
|
-
[linkAvatarError]="'https://example.com/
|
|
87
|
-
[textAvatar]="'
|
|
72
|
+
[linkAvatarError]="'https://example.com/fallback.jpg'"
|
|
73
|
+
[textAvatar]="'John Doe'"
|
|
88
74
|
[idGenColor]="'user-123'"
|
|
89
|
-
[size]="40"
|
|
90
|
-
|
|
75
|
+
[size]="40" />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3. Avatar rectangle
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<libs_ui-components-avatar
|
|
82
|
+
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
83
|
+
[typeShape]="'rectangle'"
|
|
84
|
+
[size]="48" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 4. Avatar với preview
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<libs_ui-components-avatar
|
|
91
|
+
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
92
|
+
[clickPreviewImage]="true"
|
|
93
|
+
[zIndexPreviewImage]="1000"
|
|
94
|
+
[size]="64" />
|
|
91
95
|
```
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
### 5. Avatar với custom classes
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
-
|
|
99
|
+
```html
|
|
100
|
+
<libs_ui-components-avatar
|
|
101
|
+
[linkAvatar]="'https://example.com/avatar.jpg'"
|
|
102
|
+
[classInclude]="'mr-4 mb-2'"
|
|
103
|
+
[classImageInclude]="'rounded-lg'"
|
|
104
|
+
[size]="32" />
|
|
105
|
+
```
|
|
97
106
|
|
|
98
|
-
## API
|
|
107
|
+
## API
|
|
99
108
|
|
|
100
|
-
###
|
|
109
|
+
### libs_ui-components-avatar
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
| --------------------- | ---------------------------------- | ------------ | ---------------------------------------------------------------------- |
|
|
104
|
-
| linkAvatar | `string` | - | Đường dẫn của hình ảnh avatar |
|
|
105
|
-
| linkAvatarError | `string` | - | Đường dẫn của hình ảnh thay thế khi avatar chính bị lỗi |
|
|
106
|
-
| textAvatar | `string` | - | Văn bản hiển thị khi không có hình ảnh (thường là chữ cái đầu của tên) |
|
|
107
|
-
| idGenColor | `string` | - | ID dùng để tạo màu nền tự động khi sử dụng văn bản |
|
|
108
|
-
| size | `16 \| 24 \| 32 \| 40 \| 48 \| 64` | `32` | Kích thước của avatar (tính bằng pixel) |
|
|
109
|
-
| typeShape | `'circle' \| 'rectangle'` | `'circle'` | Hình dạng của avatar (tròn hoặc vuông) |
|
|
110
|
-
| classInclude | `string` | `'mr-[8px]'` | CSS class bổ sung cho container chính |
|
|
111
|
-
| classImageInclude | `string` | `''` | CSS class bổ sung cho thẻ img |
|
|
112
|
-
| getLastTextAfterSpace | `boolean` | `false` | Nếu true, chỉ lấy chữ cái đầu tiên của từ cuối cùng trong textAvatar |
|
|
113
|
-
| clickPreviewImage | `boolean` | `false` | Cho phép click vào avatar để mở xem ảnh preview |
|
|
111
|
+
#### Inputs
|
|
114
112
|
|
|
115
|
-
|
|
113
|
+
| Property | Type | Default | Description |
|
|
114
|
+
|----------|------|---------|-------------|
|
|
115
|
+
| `[typeShape]` | `TYPE_SHAPE_AVATAR \| undefined` | `'circle'` | Hình dạng avatar: 'circle' hoặc 'rectangle' |
|
|
116
|
+
| `[classInclude]` | `string \| undefined` | `'mr-[8px]'` | Class CSS tùy chỉnh cho container |
|
|
117
|
+
| `[size]` | `TYPE_SIZE_AVATAR_CONFIG \| undefined` | `32` | Kích thước avatar: 16, 24, 32, 40, 48, 64 |
|
|
118
|
+
| `[linkAvatar]` | `string` | `-` | URL ảnh avatar chính |
|
|
119
|
+
| `[linkAvatarError]` | `string` | `-` | URL ảnh fallback khi `linkAvatar` lỗi |
|
|
120
|
+
| `[classImageInclude]` | `string \| undefined` | `''` | Class CSS tùy chỉnh cho thẻ img |
|
|
121
|
+
| `[zIndexPreviewImage]` | `number` | `-` | Z-index cho gallery viewer khi preview |
|
|
122
|
+
| `[clickPreviewImage]` | `boolean` | `-` | Bật preview ảnh khi click |
|
|
123
|
+
| `[idGenColor]` | `string` | `-` | ID để generate màu nền (hash color) |
|
|
124
|
+
| `[getLastTextAfterSpace]` | `boolean` | `-` | Lấy text cuối cùng sau khoảng trắng (phải truyền TRƯỚC textAvatar) |
|
|
125
|
+
| `[textAvatar]` | `string \| undefined` | `''` | Text hiển thị khi không có ảnh (tự động clean unicode và ký tự đặc biệt) |
|
|
126
|
+
| `[textAvatarClassInclude]` | `string` | `''` | Class CSS tùy chỉnh cho text |
|
|
127
|
+
| `[containertextAvatarClassInclude]` | `string` | `''` | Class CSS tùy chỉnh cho container text |
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
| -------------- | ------------ | ------------------------------------------------------------------------ |
|
|
119
|
-
| outAvatarError | `void` | Sự kiện được kích hoạt khi linkAvatar bị lỗi và không có linkAvatarError |
|
|
129
|
+
#### Outputs
|
|
120
130
|
|
|
121
|
-
|
|
131
|
+
| Property | Type | Description |
|
|
132
|
+
|----------|------|-------------|
|
|
133
|
+
| `(outAvatarError)` | `EventEmitter<void>` | Emit khi cả `linkAvatar` và `linkAvatarError` đều lỗi |
|
|
134
|
+
| `(outEventPreviewImage)` | `EventEmitter<'open' \| 'remove'>` | Emit khi mở/đóng gallery viewer |
|
|
122
135
|
|
|
123
|
-
|
|
136
|
+
## Types & Interfaces
|
|
124
137
|
|
|
125
138
|
```typescript
|
|
139
|
+
export type TYPE_SIZE_AVATAR_CONFIG = 16 | 24 | 32 | 40 | 48 | 64;
|
|
140
|
+
|
|
141
|
+
export type TYPE_SHAPE_AVATAR = 'circle' | 'rectangle';
|
|
142
|
+
|
|
126
143
|
export interface IAvatarConfig {
|
|
127
144
|
classImageInclude?: string;
|
|
128
145
|
classInclude?: string;
|
|
@@ -134,131 +151,59 @@ export interface IAvatarConfig {
|
|
|
134
151
|
typeShape?: TYPE_SHAPE_AVATAR;
|
|
135
152
|
getLastTextAfterSpace?: boolean;
|
|
136
153
|
}
|
|
137
|
-
|
|
138
|
-
export type TYPE_SIZE_AVATAR_CONFIG = 16 | 24 | 32 | 40 | 48 | 64;
|
|
139
|
-
export type TYPE_SHAPE_AVATAR = 'circle' | 'rectangle';
|
|
140
154
|
```
|
|
141
155
|
|
|
142
|
-
|
|
156
|
+
### Type Descriptions
|
|
143
157
|
|
|
144
|
-
|
|
158
|
+
- **TYPE_SIZE_AVATAR_CONFIG**: Các kích thước avatar được hỗ trợ. Font size của text sẽ tự động điều chỉnh theo size.
|
|
159
|
+
- **TYPE_SHAPE_AVATAR**: Hình dạng avatar. 'circle' có border-radius 50%, 'rectangle' có border-radius 4px.
|
|
160
|
+
- **IAvatarConfig**: Interface để định nghĩa object config, hữu ích khi truyền config từ parent component.
|
|
145
161
|
|
|
146
|
-
|
|
162
|
+
## Styling
|
|
147
163
|
|
|
148
|
-
|
|
149
|
-
import { Component } from '@angular/core';
|
|
150
|
-
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
|
|
164
|
+
### CSS Classes
|
|
151
165
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
})
|
|
158
|
-
export class UserAvatarComponent {
|
|
159
|
-
user = {
|
|
160
|
-
id: 'user-123',
|
|
161
|
-
name: 'Nguyễn Văn A',
|
|
162
|
-
avatar: 'https://example.com/avatar.jpg',
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
handleAvatarError() {
|
|
166
|
-
console.log('Không thể tải được hình ảnh avatar');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
```
|
|
166
|
+
| Class | Description |
|
|
167
|
+
|-------|-------------|
|
|
168
|
+
| `.libs_ui-component-avatar` | Container chính của avatar |
|
|
169
|
+
| `.libs_ui-component-avatar-rectangle` | Class khi `typeShape = 'rectangle'` |
|
|
170
|
+
| `.libs_ui-component-avatar-icon` | Container cho text/icon fallback |
|
|
170
171
|
|
|
171
|
-
|
|
172
|
+
### CSS Variables
|
|
172
173
|
|
|
173
|
-
|
|
174
|
-
<libs_ui-components-avatar
|
|
175
|
-
[linkAvatar]="user.avatar"
|
|
176
|
-
[textAvatar]="user.name"
|
|
177
|
-
[idGenColor]="user.id"
|
|
178
|
-
[size]="40"
|
|
179
|
-
(outAvatarError)="handleAvatarError()"></libs_ui-components-avatar>
|
|
180
|
-
```
|
|
174
|
+
Component không sử dụng CSS variables, màu nền được generate từ `idGenColor` thông qua hàm hash.
|
|
181
175
|
|
|
182
|
-
|
|
176
|
+
## Công nghệ
|
|
183
177
|
|
|
184
|
-
|
|
178
|
+
| Technology | Version | Purpose |
|
|
179
|
+
|------------|---------|---------|
|
|
180
|
+
| Angular | 18+ | Framework |
|
|
181
|
+
| Angular Signals | - | State management |
|
|
182
|
+
| TailwindCSS | 3.x | Styling |
|
|
183
|
+
| OnPush | - | Change Detection |
|
|
185
184
|
|
|
186
|
-
|
|
187
|
-
import { Component } from '@angular/core';
|
|
188
|
-
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
|
|
185
|
+
## Demo
|
|
189
186
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
standalone: true,
|
|
193
|
-
imports: [LibsUiComponentsAvatarComponent],
|
|
194
|
-
templateUrl: './avatar-group.component.html',
|
|
195
|
-
})
|
|
196
|
-
export class AvatarGroupComponent {
|
|
197
|
-
users = [
|
|
198
|
-
{
|
|
199
|
-
id: 'user-1',
|
|
200
|
-
name: 'Nguyễn Văn A',
|
|
201
|
-
avatar: 'https://example.com/avatar1.jpg',
|
|
202
|
-
size: 64,
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
id: 'user-2',
|
|
206
|
-
name: 'Trần Thị B',
|
|
207
|
-
avatar: 'https://example.com/avatar2.jpg',
|
|
208
|
-
size: 48,
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
id: 'user-3',
|
|
212
|
-
name: 'Lê Văn C',
|
|
213
|
-
avatar: 'https://example.com/avatar3.jpg',
|
|
214
|
-
size: 32,
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
id: 'user-4',
|
|
218
|
-
name: 'Phạm Thị D',
|
|
219
|
-
avatar: null,
|
|
220
|
-
size: 24,
|
|
221
|
-
},
|
|
222
|
-
];
|
|
223
|
-
}
|
|
187
|
+
```bash
|
|
188
|
+
npx nx serve core-ui
|
|
224
189
|
```
|
|
225
190
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
```html
|
|
229
|
-
<div class="flex items-center space-x-2">
|
|
230
|
-
@for (user of users; track user.id) {
|
|
231
|
-
<libs_ui-components-avatar
|
|
232
|
-
[linkAvatar]="user.avatar"
|
|
233
|
-
[textAvatar]="user.name"
|
|
234
|
-
[idGenColor]="user.id"
|
|
235
|
-
[size]="user.size"
|
|
236
|
-
[typeShape]="user.id === 'user-4' ? 'rectangle' : 'circle'"></libs_ui-components-avatar>
|
|
237
|
-
}
|
|
238
|
-
</div>
|
|
239
|
-
```
|
|
191
|
+
Truy cập: `http://localhost:4500/avatar`
|
|
240
192
|
|
|
241
|
-
##
|
|
193
|
+
## Unit Tests
|
|
242
194
|
|
|
243
|
-
|
|
195
|
+
```bash
|
|
196
|
+
# Chạy tests
|
|
197
|
+
npx nx test components-avatar
|
|
244
198
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
import { LibsUiComponentsAvatarDemoComponent } from '@libs-ui/components-avatar';
|
|
199
|
+
# Coverage
|
|
200
|
+
npx nx test components-avatar --coverage
|
|
248
201
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
standalone: true,
|
|
252
|
-
imports: [LibsUiComponentsAvatarDemoComponent],
|
|
253
|
-
template: `
|
|
254
|
-
<lib-avatar-demo></lib-avatar-demo>
|
|
255
|
-
`,
|
|
256
|
-
})
|
|
257
|
-
export class AvatarDemoComponent {}
|
|
202
|
+
# Watch mode
|
|
203
|
+
npx nx test components-avatar --watch
|
|
258
204
|
```
|
|
259
205
|
|
|
260
|
-
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
MIT
|
|
261
209
|
|
|
262
|
-
```html
|
|
263
|
-
<lib-avatar-demo></lib-avatar-demo>
|
|
264
|
-
```
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-avatar",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.356-0",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/core": ">=18.0.0",
|
|
6
|
-
"@libs-ui/interfaces-types": "0.2.
|
|
7
|
-
"@libs-ui/utils": "0.2.
|
|
6
|
+
"@libs-ui/interfaces-types": "0.2.356-0",
|
|
7
|
+
"@libs-ui/utils": "0.2.356-0"
|
|
8
8
|
},
|
|
9
9
|
"sideEffects": false,
|
|
10
10
|
"module": "fesm2022/libs-ui-components-avatar.mjs",
|