Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESL Avatar #2052

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
41ca919
feat(esl-avatar): initial implementation of avatar component
dshovchko Aug 22, 2022
4a68413
docs(esl-avatar): create examples page of ESL Avatar component
dshovchko Aug 23, 2022
7fc2090
docs(esl-avatar): add styles for ESL Avatar examples page
dshovchko Aug 23, 2022
a1bd1a4
Merge branch 'main' into epic/avatar
dshovchko Nov 10, 2022
dac696c
Merge branch 'epic/avatar' into feat/create-esl-avatal
dshovchko Nov 10, 2022
ec292ae
style(esl-avatal): fix stylelint issue
dshovchko Nov 10, 2022
8e68068
Merge remote-tracking branch 'origin/main' into epic/avatar
dshovchko Nov 23, 2022
af565dc
Merge remote-tracking branch 'origin/main' into epic/avatar
dshovchko Dec 9, 2022
b6a224f
Merge remote-tracking branch 'origin/main' into epic/avatar
dshovchko Jan 16, 2023
34e811a
Merge branch 'main' into epic/avatar
dshovchko Mar 1, 2023
2e561f4
Merge remote-tracking branch 'origin/main' into epic/avatar
dshovchko Mar 24, 2023
51fdbde
Merge remote-tracking branch 'origin/epic/avatar' into feat/create-es…
dshovchko Mar 24, 2023
59aa669
Merge remote-tracking branch 'origin/main' into epic/avatar
dshovchko Nov 9, 2023
d9609b9
Merge branch 'epic/avatar' into feat/create-esl-avatal
dshovchko Nov 9, 2023
d0e61fc
refactor(esl-avatar): component refactoring
dshovchko Nov 10, 2023
1399bb0
docs(esl-avatar): update examples page of ESL Avatar component
dshovchko Nov 10, 2023
be10c77
style(esl-avatar): add jsx tag shape
dshovchko Nov 10, 2023
c7123a7
refactor(esl-avatar): improove component
dshovchko Nov 14, 2023
8e4fe2c
docs(esl-avatar): update demo
dshovchko Nov 14, 2023
e3a22bf
test(esl-avatar): create test of component
dshovchko Nov 14, 2023
e97dbc3
style(esl-avatar): update shape for TSX
dshovchko Nov 15, 2023
d29ff23
Merge branch 'epic/avatar' of github.com:exadel-inc/esl into feat/cre…
ala-n Nov 16, 2023
52e76e9
refactor(esl-avatar): apply suggestions from code review
dshovchko Dec 6, 2023
a2ce229
test(esl-avatar): uodate tests of component
dshovchko Dec 6, 2023
56bad5d
docs(esl-avatar): update demo
dshovchko Dec 6, 2023
7846b99
docs(esl-avatar): add README
dshovchko Dec 7, 2023
3ad6729
style(esl-avatar): update tag shape
dshovchko Dec 7, 2023
abc0484
Merge branch 'epic/avatar' into feat/create-esl-avatal
dshovchko Dec 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pages/src/localdev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ESLTooltip,
ESLAnimate,
ESLAnimateMixin,
ESLAvatar,
ESLRelatedTarget
} from '@exadel/esl/modules/all';

Expand Down Expand Up @@ -109,6 +110,8 @@ ESLTooltip.register();
ESLAnimate.register();
ESLAnimateMixin.register();

ESLAvatar.register();

// Register ESL Mixins
ESLRelatedTarget.register();

Expand Down
Binary file added pages/static/assets/avatar/animation.webp
Binary file not shown.
Binary file added pages/static/assets/avatar/transparent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pages/static/assets/avatar/transparent.webp
Binary file not shown.
Binary file added pages/static/assets/avatar/user.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pages/static/assets/avatar/user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions pages/static/assets/avatar/user.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pages/static/assets/avatar/user.webp
Binary file not shown.
9 changes: 9 additions & 0 deletions pages/static/assets/examples/avatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions pages/views/components/esl-avatar.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
layout: content
title: ESL Avatar
seoTitle: ESL Avatar is a custom element used to represent a user's profile picture
name: ESL Avatar
tags: [components, beta]
aside:
source: src/modules/esl-avatar
examples:
- avatar
---

{% mdRender 'src/modules/esl-avatar/README.md', 'intro' %}
243 changes: 243 additions & 0 deletions pages/views/examples/avatar.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
---
layout: content
title: Avatar
seoTitle: Avatar component examples based on ESL web components
name: Avatar
tags: [examples, beta]
icon: examples/avatar.svg
aside:
components:
- esl-avatar
---

{% macro avatarElement(class, src, username, loading) %}
<esl-avatar class="{{class}}"{% if src %} src="{{src}}"{% endif %}{% if username%} username="{{username}}"{% endif %}{% if loading %} loading="{{loading}}"{% endif %}></esl-avatar>
{% endmacro %}

{% macro avatarDemo(src, username, loading) %}
<div class="avatar-demo-wrapper">
{{ avatarElement('avatar-demo-1', src, username, loading) }}
{{ avatarElement('avatar-demo-2', src, username, loading) }}
{{ avatarElement('avatar-demo-3', src, username, loading) }}
{{ avatarElement('avatar-demo-4', src, username, loading) }}
</div>
{% endmacro %}

<style>
.avatar-demo-container {
justify-content: center;
margin-block: 40px;
}

.avatar-demo-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: center;

esl-avatar {
margin: 0 5px;
}
}

.avatar-demo-1 {
background: #ffa500;
font-size: 12px;
font-weight: 300;
}

.avatar-demo-2 {
--esl-avatar-size: 60px;

background: #000;
font-size: 25px;
color: #ff0;
font-weight: 900;
}

.avatar-demo-3 {
--esl-avatar-size: 120px;

background: radial-gradient(circle, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 13%, rgba(0,212,255,1) 100%);
font-size: 60px;
color: #ff69b4;
border: 1px solid #ff0;
box-shadow: 0px 0px 10px 2px rgba(255, 255, 0, .2);
font-weight: 700;
}

.avatar-demo-4 {
--esl-avatar-size: 180px;

background: #f00;
font-size: 90px;
border: 9px solid #afeeee;
font-weight: 900;
}
</style>

<section class="row">
<div class="col-12">
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>Avatar without image, text abbreviation only</h2>
{% code 'html' %}
<esl-avatar
username="ESL Developer">
</esl-avatar>
{% endcode %}
<p>ESL Avatar displays the user's initials. (The first letter from the first word of the username and the first letter from the second word if it exists.).</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('', 'ESL Developer', '') }}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>The component with JPEG image</h2>
{% code 'html' %}
<esl-avatar
username="Lead Developer"
src="/assets/avatar/user.jpg">
</esl-avatar>
{% endcode %}
<p>ESL Avatar displays an avatar image.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/user.jpg', 'Lead Developer', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>Avatar with PNG image</h2>
{% code 'html' %}
<esl-avatar
username="Senior Developer"
src="/assets/avatar/user.png">
</esl-avatar>
{% endcode %}
<p>The component displays an avatar image.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/user.png', 'Senior Developer', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With transparent PNG image (3:2 ratio)</h2>
{% code 'html' %}
<esl-avatar
username="ESL Bot"
src="/assets/avatar/transparent.png">
</esl-avatar>
{% endcode %}
<p>It should be noted that the image is not square, but rectangular, the ratio is 3 to 2. As you can see, the component shows the image with the original ratio preserved in such a way that the image covers the entire plane of the component.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/transparent.png', 'ESL Bot', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With SVG image (and eager loading policy)</h2>
{% code 'html' %}
<esl-avatar
loading="eager"
username="Anonymous Developer"
src="/assets/avatar/user.svg">
</esl-avatar>
{% endcode %}
<p>The component displays an avatar image and the image will be loaded as soon as possible.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/user.svg', 'Anonymous Developer', 'eager')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With WEBP image (and lazy loading policy)</h2>
{% code 'html' %}
<esl-avatar
loading="lazy"
username="Junior Developer"
src="/assets/avatar/user.webp">
</esl-avatar>
{% endcode %}
<p>It will show the image, but the loading of the image by the browser will be delayed until it appears in the browser's viewport. The behavior is identical to the loading="lazy" mode for image tags. But lazy loading mode is enabled by default.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/user.webp', 'Junior Developer', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With transparent WEBP image (3:2 ratio)</h2>
{% code 'html' %}
<esl-avatar
username="Intern Developer"
src="/assets/avatar/transparent.webp">
</esl-avatar>
{% endcode %}
<p>It should be noted that the image is not square, but rectangular, the ratio is 3 to 2. As you can see, the component shows the image with the original ratio preserved in such a way that the image covers the entire plane of the component.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/transparent.webp', 'Intern Developer', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With animated WEBP image</h2>
{% code 'html' %}
<esl-avatar
username="Bored Developer"
src="/assets/avatar/animation.webp">
</esl-avatar>
{% endcode %}
<p>WOW!!! Live avatar!</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/avatar/animation.webp', 'Bored Developer', '')}}
</div>
</div>
<hr/>
<div class="row mb-4">
<div class="col-sm-12 col-md-6">
<div>
<h2>With image, but the image did not load</h2>
{% code 'html' %}
<esl-avatar
username="Non-existetnt Developer"
src="/assets/non-existent-image.png">
</esl-avatar>
{% endcode %}
<p>The component tries to load the image and switches to text mode displaying when it receives the error.</p>
</div>
</div>
<div class="col-sm-12 col-md-6 d-flex avatar-demo-container">
{{ avatarDemo('/assets/non-existent-image.png', 'Non-existetnt Developer', '')}}
</div>
</div>
</div>
</section>
2 changes: 2 additions & 0 deletions src/modules/all.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
@import './esl-animate/core.less';

@import './esl-share/core.less';

@import './esl-avatar/core.less';
3 changes: 3 additions & 0 deletions src/modules/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export * from './esl-tooltip/core';
// Animate
export * from './esl-animate/core';

// Avatar
export * from './esl-avatar/core';

// Related Target Mixin
export * from './esl-related-target/core';

Expand Down
32 changes: 32 additions & 0 deletions src/modules/esl-avatar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# [ESL](../../../) Avatar

Version: *1.0.0-beta*.

Authors: *Dmytro Shovchko*.

***Important Notice: the component is under beta version, it is tested and ready to use but be aware of its potential critical API changes.***

<a name="intro"></a>

**ESLAvatar** is a versatile UI element representing a user with profile pictures or initials.

The component works as follows. If the consumer has specified the `src` attribute with the profile picture URL, the component will try to display the image in the inner content.

If the URL of the picture is not specified or an error occurs when loading the image, the component will switch to text mode. In text mode, it displays the initials from the username or in simple words, just the first letters of each word in the username. The length of this username abbreviation is limited by the `abbr-length` parameter and defaults to 2.

### Attributes:

- `abbr-length` - the limit number of letters to be displayed in text-only mode
- `loading` - policy of loading image that is outside of the viewport
- `src` - URL of the avatar picture
- `username` - the name of the user for whom the avatar is displayed.

### API

- `abbr` - getter that returns an abbreviation to display in text-only mode and for alt property of image
- `init` - initializes inner content of the component.

### Events

- `esl:avatar:changed` - event to dispatch on change of ESLAvatar

1 change: 1 addition & 0 deletions src/modules/esl-avatar/core.less
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import './core/esl-avatar.less';
1 change: 1 addition & 0 deletions src/modules/esl-avatar/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './core/esl-avatar';
29 changes: 29 additions & 0 deletions src/modules/esl-avatar/core/esl-avatar.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
esl-avatar {
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.3s ease-in-out;
opacity: 0;
border-radius: 50%;
width: var(--esl-avatar-size, 32px);
min-width: var(--esl-avatar-size, 32px);
height: var(--esl-avatar-size, 32px);
min-height: var(--esl-avatar-size, 32px);
overflow: hidden;
text-transform: uppercase;
line-height: 1em;

&[with-image] {
background: transparent;
}

&[ready] {
opacity: 1;
}

.esl-avatar-img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
Loading