ACS-8315: avatar component (#9931)

This commit is contained in:
Denys Vuika
2024-07-09 17:58:41 -04:00
committed by GitHub
parent eaa489ae8d
commit a0b82ad887
10 changed files with 265 additions and 3 deletions

View File

@@ -0,0 +1,7 @@
<div class="adf-avatar">
<img *ngIf="src; else initialsTemplate" class="adf-avatar__image" [src]="src" [alt]="initials" [title]="tooltip" />
</div>
<ng-template #initialsTemplate>
<div class="adf-avatar__image adf-avatar__initials" [title]="tooltip">{{ initials }}</div>
</ng-template>

View File

@@ -0,0 +1,78 @@
# Avatar Component
`standalone`, `component`
The Avatar component is a simple component that can be used to display user avatars.
## Usage
Displaying an avatar with an image and initials fallback:
```html
<adf-avatar
size="32px"
src="https://avatars.githubusercontent.com/u/503991?v=4&size=64"
initials="DV"
tooltip="Denys Vuika"
>
</adf-avatar>
```
Integrating with context menu:
```html
<adf-avatar
size="32px"
src="https://avatars.githubusercontent.com/u/503991?v=4&size=64"
initials="DV"
tooltip="Denys Vuika"
cursor="pointer"
[matMenuTriggerFor]="userMenu">
</adf-avatar>
<mat-menu #userMenu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
```
## API
Import the following standalone components:
```typescript
import { AvatarComponent } from '@alfresco/adf-core';
```
## Properties
| Name | Type | Default | Description |
|------------|--------|---------|--------------------------------------------------------|
| `size` | string | `32px` | The size of the avatar. |
| `src` | string | | The URL of the image to display. |
| `initials` | string | | The initials to display if the image is not available. |
| `tooltip` | string | | The tooltip to display when hovering over the avatar. |
| `cursor` | string | `auto` | The cursor style. |
## Theming
The following CSS classes are available for theming:
| Name | Description |
|------------------------|-----------------------|
| `adf-avatar` | The host element. |
| `adf-avatar__image` | The image element. |
| `adf-avatar__initials` | The initials element. |
### CSS Variables
| Name | Default | Description |
|---------------------------------|-----------|-------------------------------------|
| `--adf-avatar-size` | `32px` | The size of the avatar. |
| `--adf-avatar-border-radius` | `50%` | The border radius of the avatar. |
| `--adf-avatar-background-color` | `#f3f3f3` | The background color of the avatar. |
| `--adf-avatar-color` | `#333` | The text color of the initials. |
| `--adf-avatar-font-size` | `14px` | The font size of the initials. |
| `--adf-avatar-font-weight` | `500` | The font weight of the initials. |
| `--adf-avatar-cursor` | `auto` | The cursor style. |
```

View File

@@ -0,0 +1,20 @@
.adf-avatar {
display: flex;
}
.adf-avatar__image {
cursor: var(--adf-avatar-cursor, auto);
display: inline-block;
overflow: hidden;
line-height: 1;
border-radius: var(--adf-avatar-border-radius, 50%);
width: var(--adf-avatar-size, 32px);
height: var(--adf-avatar-size, 32px);
color: var(--adf-avatar-color, #333);
background-color: var(--adf-avatar-background-color, #f3f3f3);
box-shadow: 0 0 0 1px var(--adf-avatar-border-color, rgba(31, 35, 40, 0.15));
font-size: var(--adf-avatar-font-size, 14px);
font-weight: var(--adf-avatar-font-weight, 500);
text-align: center;
align-content: center;
}

View File

@@ -0,0 +1,89 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AvatarComponent } from '@alfresco/adf-core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
describe('AvatarComponent', () => {
let component: AvatarComponent;
let fixture: ComponentFixture<AvatarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AvatarComponent]
}).compileComponents();
fixture = TestBed.createComponent(AvatarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should display initials when src is not provided', () => {
component.src = '';
fixture.detectChanges();
const avatarElement: HTMLElement = fixture.nativeElement.querySelector('.adf-avatar__initials');
expect(avatarElement.textContent).toContain(component.initials);
});
it('should display image when src is provided', () => {
component.src = 'path/to/image.jpg';
fixture.detectChanges();
const imgElement: HTMLImageElement = fixture.nativeElement.querySelector('.adf-avatar__image');
expect(imgElement.src).toContain(component.src);
});
it('should use default initials when not provided', () => {
fixture.detectChanges();
const avatarElement: HTMLElement = fixture.nativeElement.querySelector('.adf-avatar__initials');
expect(avatarElement.textContent).toContain('U');
});
it('should use custom initials', () => {
component.initials = 'DV';
fixture.detectChanges();
const avatarElement: HTMLElement = fixture.nativeElement.querySelector('.adf-avatar__initials');
expect(avatarElement.textContent).toContain('DV');
});
it('should apply custom size style when size is provided', () => {
component.size = '48px';
fixture.detectChanges();
const style = getComputedStyle(fixture.nativeElement.querySelector('.adf-avatar__image'));
expect(style.width).toBe('48px');
expect(style.height).toBe('48px');
});
it('should apply custom cursor style when cursor is provided', () => {
component.cursor = 'pointer';
fixture.detectChanges();
const style = getComputedStyle(fixture.nativeElement.querySelector('.adf-avatar__image'));
expect(style.cursor).toBe('pointer');
});
it('should display tooltip when provided', () => {
component.tooltip = 'User Tooltip';
fixture.detectChanges();
const avatarElement: HTMLElement = fixture.nativeElement.querySelector('.adf-avatar__image');
expect(avatarElement.getAttribute('title')).toBe('User Tooltip');
});
});

View File

@@ -0,0 +1,46 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, HostBinding, Input, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'adf-avatar',
standalone: true,
imports: [CommonModule],
templateUrl: './avatar.component.html',
styleUrls: ['./avatar.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class AvatarComponent {
@Input()
src: string;
@Input()
initials: string = 'U';
@Input()
tooltip: string = '';
@HostBinding('style.--adf-avatar-size')
@Input()
size = getComputedStyle(document.documentElement).getPropertyValue('--adf-avatar-size');
@HostBinding('style.--adf-avatar-cursor')
@Input()
cursor = getComputedStyle(document.documentElement).getPropertyValue('--adf-avatar-cursor');
}

View File

@@ -16,6 +16,7 @@
*/
export * from './lib/about/index';
export * from './lib/avatar/avatar.component';
export * from './lib/button/button.component';
export * from './lib/viewer/index';
export * from './lib/toolbar/index';