ng-hub-ui-avatar
Version:
A universal avatar component for Angular applications that fetches / generates avatar based on the information you have about the user. Supports initials, Gravatar integration, custom images and styling options. Perfect for user profiles and comment syste
446 lines (334 loc) • 21.6 kB
Markdown
# ng-hub-ui-avatar
[Español](./README.es.md) | **English**
[](https://www.npmjs.com/package/ng-hub-ui-avatar)
[](https://www.npmjs.com/package/ng-hub-ui-avatar)
[](https://github.com/carlos-morcillo/ng-hub-ui-avatar/blob/main/LICENSE)
A universal avatar component for Angular applications that renders avatars from multiple sources (Gravatar, GitHub, Facebook, custom images, initials or plain text) and applies an automatic fallback strategy when a source fails.
> **⚠️ BREAKING CHANGES:** Version 21.1.0 removes the need for public stylesheet imports. Styles are now encapsulated within the component. Please read the [BREAKING_CHANGES.md](./BREAKING_CHANGES.md) file before upgrading.
## Documentation and Live Examples
This package is part of [Hub UI](https://hubui.dev/), a collection of Angular component libraries for standalone apps.
- Docs: https://hubui.dev/avatar/overview/
- Live examples: https://hubui.dev/avatar/examples/
- Hub UI: https://hubui.dev/
## 🧩 Library Family `ng-hub-ui`
This library is part of the **Hub UI** ecosystem:
- [ng-hub-ui-accordion](https://www.npmjs.com/package/ng-hub-ui-accordion) (deprecated — use ng-hub-ui-panels)
- [ng-hub-ui-action-sheet](https://www.npmjs.com/package/ng-hub-ui-action-sheet)
- [ng-hub-ui-avatar](https://www.npmjs.com/package/ng-hub-ui-avatar) ← You are here
- [ng-hub-ui-board](https://www.npmjs.com/package/ng-hub-ui-board)
- [ng-hub-ui-breadcrumbs](https://www.npmjs.com/package/ng-hub-ui-breadcrumbs)
- [ng-hub-ui-calendar](https://www.npmjs.com/package/ng-hub-ui-calendar)
- [ng-hub-ui-dropdown](https://www.npmjs.com/package/ng-hub-ui-dropdown)
- [ng-hub-ui-ds](https://www.npmjs.com/package/ng-hub-ui-ds)
- [ng-hub-ui-forms](https://www.npmjs.com/package/ng-hub-ui-forms)
- [ng-hub-ui-history](https://www.npmjs.com/package/ng-hub-ui-history)
- [ng-hub-ui-milestones](https://www.npmjs.com/package/ng-hub-ui-milestones)
- [ng-hub-ui-modal](https://www.npmjs.com/package/ng-hub-ui-modal)
- [ng-hub-ui-nav](https://www.npmjs.com/package/ng-hub-ui-nav)
- [ng-hub-ui-paginable](https://www.npmjs.com/package/ng-hub-ui-paginable)
- [ng-hub-ui-panels](https://www.npmjs.com/package/ng-hub-ui-panels)
- [ng-hub-ui-portal](https://www.npmjs.com/package/ng-hub-ui-portal)
- [ng-hub-ui-skeleton](https://www.npmjs.com/package/ng-hub-ui-skeleton)
- [ng-hub-ui-sortable](https://www.npmjs.com/package/ng-hub-ui-sortable)
- [ng-hub-ui-stepper](https://www.npmjs.com/package/ng-hub-ui-stepper)
- [ng-hub-ui-utils](https://www.npmjs.com/package/ng-hub-ui-utils)
## 📑 Table of Contents
- [Documentation and Live Examples](#documentation-and-live-examples)
- [🧩 Library Family `ng-hub-ui`](#-library-family-ng-hub-ui)
- [Description](#description)
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Styling](#styling)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Support](#support)
- [License](#license)
## Description
`ng-hub-ui-avatar` is a universal avatar component for Angular applications. It can render avatars from multiple sources and apply an automatic fallback strategy when a source fails.
Supported avatar sources:
- Gravatar
- GitHub
- Facebook
- Custom image (`src`)
- Initials (`name`)
- Text value (`value`)
Fallback uses a source priority order. By default, the component tries the supported sources in their configured order until one succeeds.
> This project is a fork of [ngx-avatars](https://github.com/Heatmanofurioso/ngx-avatars), which itself continued the original avatar work. This package adapts and maintains the component for modern Angular applications.
## Features
- **Multiple Sources**: Gravatar, GitHub, Facebook, custom images, initials and plain text.
- **Projected Custom Content**: Drop any icon (FontAwesome, Material…), inline SVG, image or emoji inside `<hub-avatar>` and it is sized, centered and padded agnostically.
- **Automatic Fallback**: Configurable source priority order with graceful fallback when a source fails.
- **Initials Generation**: Builds initials avatars from a name with auto-generated background colors.
- **Async Remote Sources**: Resolves remote avatars (for example Gravatar) over HTTP with caching support.
- **Flexible Shape**: Round or square avatars with configurable corner radius and border.
- **CSS Variables**: Full theming via canonical `--hub-avatar-*` custom properties.
- **Signals API**: Modern Angular inputs/outputs built on signals.
- **Standalone-first**: `<hub-avatar>` is a standalone component — import it directly, no `NgModule` required. Customize colors, source priority order and cache behavior via `provideAvatar()`.
## Installation
```bash
npm install ng-hub-ui-avatar
```
## Quick Start
```typescript
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { provideAvatar } from 'ng-hub-ui-avatar';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(), // required for async remote sources (Gravatar, GitHub…)
provideAvatar() // optional — pass a config to customise sources/colours/cache
]
});
```
Then import the standalone component and use it in any template:
```typescript
import { Component } from '@angular/core';
import { AvatarComponent } from 'ng-hub-ui-avatar';
@Component({
selector: 'app-profile',
standalone: true,
imports: [AvatarComponent],
template: `<hub-avatar name="John Doe" [round]="true" size="64"></hub-avatar>`
})
export class ProfileComponent {}
```
> `provideAvatar()` is optional — `<hub-avatar>` works out of the box with defaults. `HttpClient` is only needed for async remote sources (Gravatar, GitHub).
## Usage
`<hub-avatar>` is a **standalone** component: import `AvatarComponent` directly into the `imports` of any standalone component (as shown above). No `NgModule` is required.
### Configuration
Customise source priority, colour palette or src-cache behaviour with `provideAvatar()`:
```typescript
import { provideAvatar } from 'ng-hub-ui-avatar';
import { AvatarSource } from 'ng-hub-ui-avatar';
providers: [
provideAvatar({
sourcePriorityOrder: [AvatarSource.CUSTOM, AvatarSource.GRAVATAR, AvatarSource.INITIALS],
colors: ['#1abc9c', '#3498db', '#9b59b6']
})
];
```
### Legacy `NgModule` (deprecated)
`AvatarModule` is still exported for backward compatibility and now simply re-exports the standalone component. It is **deprecated** — prefer importing `AvatarComponent` and using `provideAvatar()`.
```typescript
import { AvatarModule } from 'ng-hub-ui-avatar'; // deprecated
@NgModule({
imports: [AvatarModule] // AvatarModule.forRoot(config) still works too
})
export class FeatureModule {}
```
### Examples
```html
<hub-avatar gravatarId="adde9b2b981a8083cf084c63ad86f753"></hub-avatar>
<hub-avatar gravatarId="user@gmail.com"></hub-avatar>
<hub-avatar githubId="angular"></hub-avatar>
<hub-avatar facebookId="nasa"></hub-avatar>
<hub-avatar src="assets/avatar.jpg"></hub-avatar>
<hub-avatar name="John Doe"></hub-avatar>
<hub-avatar value="75%"></hub-avatar>
<hub-avatar
facebookId="userFacebookID"
name="Haithem Mosbahi"
src="assets/avatar.jpg"
value="28%"
gravatarId="adde9b2b981a8083cf084c63ad86f753"
size="100"
[round]="true"
></hub-avatar>
```
### Custom content (icons, SVG, images)
Project any content directly inside `<hub-avatar>` — an icon from any library, an inline `<svg>`, an `<img>` or even an emoji — and the avatar handles it agnostically: it centers the content, applies decent padding and clips it to the avatar shape (round or square). Font icons inherit a size and colour; inline SVG/images fill the avatar. Everything scales with `size`.
```html
<!-- FontAwesome (or any icon font) -->
<hub-avatar><i class="fa-solid fa-user"></i></hub-avatar>
<!-- Material Symbols -->
<hub-avatar size="72"><span class="material-symbols-outlined">rocket_launch</span></hub-avatar>
<!-- Inline SVG -->
<hub-avatar size="64">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2 2 7l10 5 10-5-10-5Z" /></svg>
</hub-avatar>
<!-- Emoji -->
<hub-avatar>🚀</hub-avatar>
```
It activates automatically whenever content is projected and takes precedence over the image/initials sources. The circle uses the avatar's own background (`--hub-avatar-bg-color`, the design-system accent by default) with a white foreground, so it reads as a coloured circle out of the box. Theme it with the regular `bgColor` / `fgColor` / `borderColor` inputs, and tune the sizing with the `--hub-avatar-content-*` tokens (see [Styling](#styling)).
### Module configuration (`forRoot`)
`AvatarModule.forRoot()` allows overriding module-level behavior.
```typescript
import { AvatarModule, AvatarSource } from 'ng-hub-ui-avatar';
const avatarSourcesOrder = [AvatarSource.CUSTOM, AvatarSource.INITIALS];
const avatarColors = ['#FFB6C1', '#2c3e50', '#95a5a6', '#f39c12', '#1abc9c'];
@NgModule({
imports: [
AvatarModule.forRoot({
sourcePriorityOrder: avatarSourcesOrder,
colors: avatarColors,
disableSrcCache: false
})
]
})
export class AppModule {}
```
`AvatarConfig` fields:
| Field | Type | Description |
| --------------------- | ---------------- | -------------------------------------------------------- |
| `colors` | `string[]` | Custom color palette for generated text avatars. |
| `sourcePriorityOrder` | `AvatarSource[]` | Custom fallback order across avatar sources. |
| `disableSrcCache` | `boolean` | Disables the cache for custom (image) source requests. |
`AvatarSource` enum values: `FACEBOOK`, `GRAVATAR`, `GITHUB`, `CUSTOM`, `INITIALS`, `VALUE`.
> Note: `facebookId` is kept as a best-effort compatibility source and may fail depending on external API/privacy restrictions.
## API Reference
### Inputs
| Input | Type | Default | Description |
| ---------------- | ------------------------------- | ----------- | ---------------------------------------------- |
| `facebookId` | `string \| null` | `undefined` | Facebook user id |
| `gravatarId` | `string \| null` | `undefined` | Gravatar email/hash |
| `githubId` | `string \| null` | `undefined` | GitHub user id |
| `src` | `string \| SafeUrl \| null` | `undefined` | Custom image source |
| `alt` | `string \| null` | `undefined` | Custom image alt text |
| `name` | `string \| null` | `undefined` | Text source used to generate initials |
| `value` | `string \| null` | `undefined` | Direct text avatar value |
| `size` | `number \| string` | `50` | Avatar size in px |
| `textSizeRatio` | `number` | `3` | Text size ratio (`size / textSizeRatio`) |
| `initialsSize` | `number \| string` | `0` | Max initials length (`0` means no limit) |
| `round` | `boolean` | `true` | Enables circular shape |
| `cornerRadius` | `number \| string` | `0` | Radius in px when `round` is `false` |
| `bgColor` | `string` | `undefined` | Background color override |
| `fgColor` | `string` | `#FFF` | Foreground/text color |
| `borderColor` | `string` | `undefined` | Border color (applies a 1px solid border) |
| `style` | `Record<string, any> \| string` | `{}` | Custom inline styles merged into avatar styles |
| `placeholder` | `string` | `undefined` | Reserved placeholder input |
| `referrerpolicy` | `string \| null` | `undefined` | Referrer policy for avatar image requests |
| `badge` | `string \| number \| boolean \| null` | `null` | Corner overlay. `badge` / `[badge]="true"` → a **dot**; `badge="4k"` / `[badge]="9"` → a **labelled** pill; `null` / absent → nothing. |
| `badgeColor` | `HubAvatarBadgeColor \| string \| null` | `null` | Semantic colour of the badge: `primary · secondary · success · danger · warning · info · light · dark` (→ `--hub-sys-color-*`). Any custom string also works (set `--hub-avatar-badge-color`). |
`HubAvatarBadgeColor` is an exported type covering the semantic colours: `'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark'`. Express presence with the colour: online → `success`, away → `warning`, busy → `danger`, offline → `secondary`.
### Outputs
| Output | Type | Description |
| --------------- | ---------------------- | ----------------------------------------------------------------------- |
| `clickOnAvatar` | `EventEmitter<Source>` | Fired on avatar click with the source used to render the current avatar |
The emitted `Source` payload exposes:
- `sourceType`: source type (`facebook`, `gravatar`, `github`, `custom`, `initials`, `value`).
- `sourceId`: identifier used by that source.
- `getAvatar(size)`: function that resolves the avatar URL/value.
## Styling
Styles are encapsulated within the component using canonical `--hub-avatar-*` tokens. Since version 21.1.0 you no longer need to import a global stylesheet.
Full CSS variable catalog:
- [`./docs/css-variables-reference.md`](./docs/css-variables-reference.md)
Framework-agnostic customization example:
```scss
hub-avatar {
/* size is set via the [size] input, not a CSS variable */
--hub-avatar-border-radius: 16px;
--hub-avatar-fg-color: #ffffff;
--hub-avatar-bg-color: #0d6efd;
--hub-avatar-border-width: 2px;
--hub-avatar-border-color: #0a58ca;
}
```
Bootstrap integration example (optional):
```scss
hub-avatar {
--hub-avatar-bg-color: var(--bs-primary);
--hub-avatar-fg-color: var(--bs-white);
--hub-avatar-border-color: var(--bs-border-color);
}
```
### Custom content
When you project content into `<hub-avatar>` (see [Custom content](#custom-content-icons-svg-images)), the **background is the avatar's own** (`--hub-avatar-bg-color`, the **accent colour by default**) and the icon uses the **avatar foreground** (`--hub-avatar-fg-color`, white) — so it reads as a coloured circle out of the box. Theme it with the regular `bgColor` / `fgColor` inputs (or `--hub-avatar-bg-color` / `--hub-avatar-fg-color`) just like any other avatar. Two extra tokens control the projected content's **sizing**, both relative to `--hub-avatar-size`:
| Token | Default | Description |
| -------------------------------- | ------------------------------------- | ------------------------------------------------------------------- |
| `--hub-avatar-content-padding` | `calc(var(--hub-avatar-size) * 0.2)` | Breathing room between the projected content and the avatar edge. |
| `--hub-avatar-content-icon-size` | `calc(var(--hub-avatar-size) * 0.55)` | Font size for icon fonts / emoji (inherited by the projected glyph). |
```scss
hub-avatar {
--hub-avatar-bg-color: #e7f1ff; // the avatar's own background — also the content circle
--hub-avatar-fg-color: #0d6efd; // icon colour (or set the `fgColor` input)
--hub-avatar-content-icon-size: calc(var(--hub-avatar-size) * 0.6);
}
```
### Badge (dot or labelled)
The `badge` input renders a corner overlay — a plain **dot** (great for presence) or a **labelled** pill (a count / text). Colour it with the semantic `badgeColor` input. Everything scales with the avatar.
```html
<!-- presence dot: badge (no content) + a semantic colour -->
<hub-avatar name="Ada Lovelace" badge badgeColor="success"></hub-avatar> <!-- online -->
<hub-avatar name="Grace Hopper" badge badgeColor="warning"></hub-avatar> <!-- away -->
<hub-avatar name="Alan Turing" badge badgeColor="danger"></hub-avatar> <!-- busy -->
<hub-avatar name="Linus T" badge badgeColor="secondary"></hub-avatar> <!-- offline -->
<!-- labelled badge -->
<hub-avatar name="Carlos M" badge="4k" badgeColor="danger"></hub-avatar>
```
`badgeColor` maps to `--hub-sys-color-*`. For a custom colour, set `--hub-avatar-badge-color` (per element or via the [colour-variants mixin](#colour-variants--mixins)):
```scss
hub-avatar[data-badge-color='brand'] {
--hub-avatar-badge-color: #9333ea;
}
```
Badge tokens:
| Variable | Default | Usage |
| --------------------------------- | ----------------------------------------------------- | -------------------------------------- |
| `--hub-avatar-badge-size` | `calc(var(--hub-avatar-size, 50px) * 0.28)` | Dot diameter / label min-height |
| `--hub-avatar-badge-offset` | `0px` | Inset from the bottom-end corner |
| `--hub-avatar-badge-ring-width` | `max(2px, calc(var(--hub-avatar-size, 50px) * 0.05))` | Width of the ring around the badge |
| `--hub-avatar-badge-ring-color` | `var(--hub-sys-surface-page, #fff)` | Colour of the ring around the badge |
| `--hub-avatar-badge-color` | `var(--hub-sys-color-secondary, #6c757d)` | Badge fill (semantic via `badgeColor`) |
| `--hub-avatar-badge-text-color` | `var(--hub-ref-color-white, #fff)` | Badge label text colour |
| `--hub-avatar-badge-font-size` | `calc(var(--hub-avatar-size, 50px) * 0.22)` | Badge label font size |
| `--hub-avatar-badge-padding` | `calc(var(--hub-avatar-size, 50px) * 0.08)` | Badge label inline padding |
### Colour variants & mixins
Every semantic colour works out of the box, both for the badge (`badgeColor="success"`) and as a coloured **avatar circle** (`class="hub-avatar--success"`). To (re)generate these in your own CSS — or to register a **custom colour** (e.g. a brand colour) — use the `hub-avatar-color-variants()` mixin, which emits the avatar **and** badge variants in one loop over a colour map:
```scss
@use 'ng-hub-ui-avatar/styles/mixins/avatar-theme' as avatar;
// the eight semantic colours (default)
@include avatar.hub-avatar-color-variants();
// add your own — generates <hub-avatar class="hub-avatar--brand"> and badgeColor="brand"
@include avatar.hub-avatar-color-variants((
'brand': var(--my-brand),
'accent': #00d4aa
));
```
### Avatar group
Wrap several `<hub-avatar>` in a `.hub-avatar-group` to overlap them into a stacked group; each avatar gets a ring so the edges read cleanly.
```html
<div class="hub-avatar-group">
<hub-avatar name="John Doe"></hub-avatar>
<hub-avatar name="Jane Doe"></hub-avatar>
<hub-avatar name="Sam Smith"></hub-avatar>
</div>
```
Group tokens:
| Variable | Default | Usage |
| ------------------------------ | -------------------------------------------------------- | ---------------------------------- |
| `--hub-avatar-group-overlap` | `calc(var(--hub-avatar-size, 50px) * 0.3)` | Horizontal overlap between avatars |
| `--hub-avatar-group-ring-width`| `max(2px, calc(var(--hub-avatar-size, 50px) * 0.04))` | Ring width around each avatar |
| `--hub-avatar-group-ring-color`| `var(--hub-sys-surface-page, #fff)` | Ring colour around each avatar |
### Sass theming mixin
The `hub-avatar-theme()` mixin themes an avatar in a single include — shape/surface, initials typography, projected-content sizing, the badge and the group ring. Every parameter is optional and defaults to `null`, so only the ones you pass are emitted as `--hub-avatar-*` overrides. It is token-based, with no Bootstrap dependency.
```scss
@use 'ng-hub-ui-avatar/styles/mixins/avatar-theme' as avatar;
hub-avatar.brand {
@include avatar.hub-avatar-theme(
$size: 64px,
$border-radius: 1rem,
$bg: #ede9fe,
$fg: #5b21b6,
$badge-color: #f43f5e
);
}
```
## Changelog
See [CHANGELOG.md](./CHANGELOG.md) for the full version history.
## Contributing
Contributions and collaboration are welcome.
- Fork the repository.
- Create a feature branch.
- Commit and push your changes.
- Open a pull request.
## Support
If you find this project helpful and would like to support its development, you can buy me a coffee:
[](https://buymeacoffee.com/carlosmorcillo)
- **Issues**: [GitHub Issues](https://github.com/carlos-morcillo/ng-hub-ui-avatar/issues)
- **Author**: [Carlos Morcillo](https://www.carlosmorcillo.com)
## License
This project is licensed under the MIT License.