Socket
Socket
Sign inDemoInstall

@atlaskit/avatar

Package Overview
Dependencies
Maintainers
1
Versions
244
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@atlaskit/avatar - npm Package Compare versions

Comparing version 20.5.10 to 21.0.0

14

CHANGELOG.md
# @atlaskit/avatar
## 21.0.0
### Major Changes
- [`92bb02bc46b`](https://bitbucket.org/atlassian/atlassian-frontend/commits/92bb02bc46b) - [ux] There are **no code changes required** to consume this major, but you should be aware that internal changes have been made to how `@atlaskit/avatar` loads images.
Before, the image loading behaviour was written in JS. Now, it leans on a standard HTML `img` tag if you provide a `src` prop, allowing it to rely on the browser to optimise the loading. These changes should result in faster image loading and an improved server-side rendering story.
In this version, the **breaking change is that you will no longer see a fallback icon while the image is loading**. We have intentionally removed this loading behaviour as it is no longer consistent with our native `img` behaviour-first approach, and was a source of SSR bugs. Avatar images will load either instantly from the cache, or very fast from a CDN. In the edge cases where there is an error with the image src provided, we will still fall back to a default icon.
### Patch Changes
- [`be23a6d8ee1`](https://bitbucket.org/atlassian/atlassian-frontend/commits/be23a6d8ee1) - [ux] Updates color tokens used to be more semantically accurate
## 20.5.10

@@ -4,0 +18,0 @@

2

dist/cjs/Avatar.js

@@ -41,3 +41,3 @@ "use strict";

var packageName = "@atlaskit/avatar";
var packageVersion = "20.5.10";
var packageVersion = "21.0.0";

@@ -44,0 +44,0 @@ var getStyles = function getStyles(css, _ref) {

@@ -26,7 +26,7 @@ "use strict";

// eslint-disable-next-line @repo/internal/fs/filename-pattern-match
var ICON_BACKGROUND = "var(--ds-text-inverse, ".concat((0, _colors.background)(), ")");
var ICON_BACKGROUND = "var(--ds-icon-inverse, ".concat((0, _colors.background)(), ")");
exports.ICON_BACKGROUND = ICON_BACKGROUND;
var ICON_COLOR = "var(--ds-text-subtlest, ".concat(_colors.N90, ")");
var ICON_COLOR = "var(--ds-icon-subtle, ".concat(_colors.N90, ")");
exports.ICON_COLOR = ICON_COLOR;
var avatarImageStyles = (0, _core.css)({
var avatarDefaultIconStyles = (0, _core.css)({
display: 'block',

@@ -37,11 +37,7 @@ width: '100%',

});
var loadingImageStyles = (0, _core.css)({
var avatarImageStyles = (0, _core.css)({
display: 'flex',
width: '100%',
height: '100%',
flex: '1 1 100%',
backgroundColor: 'transparent',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover'
flex: '1 1 100%'
});

@@ -62,43 +58,16 @@ /**

var _useState = (0, _react.useState)('initial'),
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
phase = _useState2[0],
setPhase = _useState2[1];
hasImageErrored = _useState2[0],
setHasImageErrored = _useState2[1];
var borderRadius = appearance === 'circle' ? '50%' : "".concat(_constants.AVATAR_RADIUS[size], "px");
var image = (0, _react.useMemo)(function () {
if (src) {
setPhase('loading');
var img = new Image();
var borderRadius = appearance === 'circle' ? '50%' : "".concat(_constants.AVATAR_RADIUS[size], "px"); // If src changes, reset state
img.onload = function () {
return setPhase('loaded');
};
img.onerror = function () {
return setPhase('error');
};
img.src = src;
return img;
}
return null;
(0, _react.useEffect)(function () {
setHasImageErrored(false);
}, [src]);
(0, _react.useEffect)(function () {
return function () {
if (image) {
image.onload = function () {};
image.onerror = function () {};
}
};
}, [image]);
var imageHasLoadedAsync = src && phase !== 'loading' && phase !== 'error';
var imageHasLoadedSync = src && phase === 'loading' && (image === null || image === void 0 ? void 0 : image.complete);
var imageHasLoaded = imageHasLoadedAsync || imageHasLoadedSync;
if (!imageHasLoaded) {
if (!src || hasImageErrored) {
return (0, _core.jsx)("span", {
css: [avatarImageStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
css: [avatarDefaultIconStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
// eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage

@@ -124,11 +93,13 @@ {

return (0, _core.jsx)("span", {
css: loadingImageStyles,
return (0, _core.jsx)("img", {
src: src,
alt: alt,
"data-testid": testId && "".concat(testId, "--image"),
css: avatarImageStyles,
style: {
backgroundImage: "url(\"".concat(src, "\")"),
borderRadius: borderRadius
},
role: alt ? 'img' : undefined,
"aria-label": alt || undefined,
"data-testid": testId && "".concat(testId, "--image")
onError: function onError() {
return setHasImageErrored(true);
}
});

@@ -135,0 +106,0 @@ };

{
"name": "@atlaskit/avatar",
"version": "20.5.10",
"version": "21.0.0",
"sideEffects": false
}

@@ -13,3 +13,3 @@ /** @jsx jsx */

const packageName = "@atlaskit/avatar";
const packageVersion = "20.5.10";
const packageVersion = "21.0.0";

@@ -16,0 +16,0 @@ const getStyles = (css, {

/** @jsx jsx */
// eslint-disable-next-line @repo/internal/fs/filename-pattern-match
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useState } from 'react';
import { css, jsx } from '@emotion/core';

@@ -9,5 +9,5 @@ import PersonIcon from '@atlaskit/icon/glyph/person';

import { AVATAR_RADIUS, AVATAR_SIZES } from './constants';
export const ICON_BACKGROUND = `var(--ds-text-inverse, ${background()})`;
export const ICON_COLOR = `var(--ds-text-subtlest, ${N90})`;
const avatarImageStyles = css({
export const ICON_BACKGROUND = `var(--ds-icon-inverse, ${background()})`;
export const ICON_COLOR = `var(--ds-icon-subtle, ${N90})`;
const avatarDefaultIconStyles = css({
display: 'block',

@@ -18,11 +18,7 @@ width: '100%',

});
const loadingImageStyles = css({
const avatarImageStyles = css({
display: 'flex',
width: '100%',
height: '100%',
flex: '1 1 100%',
backgroundColor: 'transparent',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover'
flex: '1 1 100%'
});

@@ -42,35 +38,12 @@ /**

}) => {
const [phase, setPhase] = useState('initial');
const borderRadius = appearance === 'circle' ? '50%' : `${AVATAR_RADIUS[size]}px`;
const image = useMemo(() => {
if (src) {
setPhase('loading');
const img = new Image();
const [hasImageErrored, setHasImageErrored] = useState(false);
const borderRadius = appearance === 'circle' ? '50%' : `${AVATAR_RADIUS[size]}px`; // If src changes, reset state
img.onload = () => setPhase('loaded');
img.onerror = () => setPhase('error');
img.src = src;
return img;
}
return null;
useEffect(() => {
setHasImageErrored(false);
}, [src]);
useEffect(() => {
return () => {
if (image) {
image.onload = () => {};
image.onerror = () => {};
}
};
}, [image]);
const imageHasLoadedAsync = src && phase !== 'loading' && phase !== 'error';
const imageHasLoadedSync = src && phase === 'loading' && (image === null || image === void 0 ? void 0 : image.complete);
const imageHasLoaded = imageHasLoadedAsync || imageHasLoadedSync;
if (!imageHasLoaded) {
if (!src || hasImageErrored) {
return jsx("span", {
css: [avatarImageStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
css: [avatarDefaultIconStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
// eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage

@@ -96,11 +69,11 @@ {

return jsx("span", {
css: loadingImageStyles,
return jsx("img", {
src: src,
alt: alt,
"data-testid": testId && `${testId}--image`,
css: avatarImageStyles,
style: {
backgroundImage: `url("${src}")`,
borderRadius: borderRadius
},
role: alt ? 'img' : undefined,
"aria-label": alt || undefined,
"data-testid": testId && `${testId}--image`
onError: () => setHasImageErrored(true)
});

@@ -107,0 +80,0 @@ };

{
"name": "@atlaskit/avatar",
"version": "20.5.10",
"version": "21.0.0",
"sideEffects": false
}

@@ -23,3 +23,3 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";

var packageName = "@atlaskit/avatar";
var packageVersion = "20.5.10";
var packageVersion = "21.0.0";

@@ -26,0 +26,0 @@ var getStyles = function getStyles(css, _ref) {

@@ -5,3 +5,3 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";

// eslint-disable-next-line @repo/internal/fs/filename-pattern-match
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useState } from 'react';
import { css, jsx } from '@emotion/core';

@@ -12,5 +12,5 @@ import PersonIcon from '@atlaskit/icon/glyph/person';

import { AVATAR_RADIUS, AVATAR_SIZES } from './constants';
export var ICON_BACKGROUND = "var(--ds-text-inverse, ".concat(background(), ")");
export var ICON_COLOR = "var(--ds-text-subtlest, ".concat(N90, ")");
var avatarImageStyles = css({
export var ICON_BACKGROUND = "var(--ds-icon-inverse, ".concat(background(), ")");
export var ICON_COLOR = "var(--ds-icon-subtle, ".concat(N90, ")");
var avatarDefaultIconStyles = css({
display: 'block',

@@ -21,11 +21,7 @@ width: '100%',

});
var loadingImageStyles = css({
var avatarImageStyles = css({
display: 'flex',
width: '100%',
height: '100%',
flex: '1 1 100%',
backgroundColor: 'transparent',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover'
flex: '1 1 100%'
});

@@ -46,43 +42,16 @@ /**

var _useState = useState('initial'),
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
phase = _useState2[0],
setPhase = _useState2[1];
hasImageErrored = _useState2[0],
setHasImageErrored = _useState2[1];
var borderRadius = appearance === 'circle' ? '50%' : "".concat(AVATAR_RADIUS[size], "px");
var image = useMemo(function () {
if (src) {
setPhase('loading');
var img = new Image();
var borderRadius = appearance === 'circle' ? '50%' : "".concat(AVATAR_RADIUS[size], "px"); // If src changes, reset state
img.onload = function () {
return setPhase('loaded');
};
img.onerror = function () {
return setPhase('error');
};
img.src = src;
return img;
}
return null;
useEffect(function () {
setHasImageErrored(false);
}, [src]);
useEffect(function () {
return function () {
if (image) {
image.onload = function () {};
image.onerror = function () {};
}
};
}, [image]);
var imageHasLoadedAsync = src && phase !== 'loading' && phase !== 'error';
var imageHasLoadedSync = src && phase === 'loading' && (image === null || image === void 0 ? void 0 : image.complete);
var imageHasLoaded = imageHasLoadedAsync || imageHasLoadedSync;
if (!imageHasLoaded) {
if (!src || hasImageErrored) {
return jsx("span", {
css: [avatarImageStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
css: [avatarDefaultIconStyles, // TODO: These dynamic SVG styles can't be set in 'style'. On a refactor, use a css custom property to pass down the size
// eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage

@@ -108,11 +77,13 @@ {

return jsx("span", {
css: loadingImageStyles,
return jsx("img", {
src: src,
alt: alt,
"data-testid": testId && "".concat(testId, "--image"),
css: avatarImageStyles,
style: {
backgroundImage: "url(\"".concat(src, "\")"),
borderRadius: borderRadius
},
role: alt ? 'img' : undefined,
"aria-label": alt || undefined,
"data-testid": testId && "".concat(testId, "--image")
onError: function onError() {
return setHasImageErrored(true);
}
});

@@ -119,0 +90,0 @@ };

{
"name": "@atlaskit/avatar",
"version": "20.5.10",
"version": "21.0.0",
"sideEffects": false
}

@@ -26,3 +26,3 @@ /** @jsx jsx */

* Used to provide better content to screen readers when using presence/status. Rather
* than a screen reader speaking "online, approved, John Smith", passing in an label
* than a screen reader speaking "online, approved, John Smith", passing in a label
* allows a custom message like "John Smith (approved and online)".

@@ -49,4 +49,3 @@ */

/**
* Name will be displayed in a tooltip, also used by screen readers as fallback
* content if the image fails to load.
* Provides alt text for the avatar image.
*/

@@ -53,0 +52,0 @@ name?: string;

@@ -11,4 +11,4 @@ /** @jsx jsx */

}
export declare const ICON_BACKGROUND: "var(--ds-text-inverse)";
export declare const ICON_COLOR: "var(--ds-text-subtlest)";
export declare const ICON_BACKGROUND: "var(--ds-icon-inverse)";
export declare const ICON_COLOR: "var(--ds-icon-subtle)";
/**

@@ -15,0 +15,0 @@ * __Avatar image__

{
"name": "@atlaskit/avatar",
"version": "20.5.10",
"version": "21.0.0",
"description": "An avatar is a visual representation of a user or entity.",

@@ -8,3 +8,3 @@ "publishConfig": {

},
"repository": "https://bitbucket.org/atlassian/atlassian-frontend",
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
"author": "Atlassian Pty Ltd",

@@ -11,0 +11,0 @@ "license": "Apache-2.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc