@instructure/ui-avatar 10.24.3-snapshot-2 → 10.24.3-snapshot-5

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/CHANGELOG.md CHANGED
@@ -3,9 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## [10.24.3-snapshot-2](https://github.com/instructure/instructure-ui/compare/v10.24.2...v10.24.3-snapshot-2) (2025-08-18)
6
+ ## [10.24.3-snapshot-5](https://github.com/instructure/instructure-ui/compare/v10.24.2...v10.24.3-snapshot-5) (2025-08-19)
7
7
 
8
- **Note:** Version bump only for package @instructure/ui-avatar
8
+
9
+ ### Bug Fixes
10
+
11
+ * **ui-avatar:** avatar now renders images correctly when using SSR ([7d8cc62](https://github.com/instructure/instructure-ui/commit/7d8cc6203bb850e1bed77cf5e85cf9ddeb03306a))
9
12
 
10
13
 
11
14
 
@@ -24,7 +24,7 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
24
24
  */
25
25
 
26
26
  import { useStyle } from '@instructure/emotion';
27
- import { useState, useEffect, forwardRef } from 'react';
27
+ import { useState, useEffect, forwardRef, useRef } from 'react';
28
28
  import { View } from '@instructure/ui-view';
29
29
  import { callRenderProp, passthroughProps } from '@instructure/ui-react-utils';
30
30
  import generateStyle from './styles';
@@ -43,7 +43,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
43
43
  showBorder = 'auto',
44
44
  shape = 'circle',
45
45
  display = 'inline-block',
46
- onImageLoaded = _event => {},
46
+ onImageLoaded,
47
47
  src,
48
48
  name,
49
49
  renderIcon,
@@ -54,6 +54,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
54
54
  elementRef,
55
55
  ...rest
56
56
  }, ref) => {
57
+ const imgRef = useRef(null);
57
58
  const _useState = useState(false),
58
59
  _useState2 = _slicedToArray(_useState, 2),
59
60
  loaded = _useState2[0],
@@ -79,6 +80,11 @@ const Avatar = /*#__PURE__*/forwardRef(({
79
80
  if (loaded && !src) {
80
81
  setLoaded(false);
81
82
  }
83
+ // Image already loaded (common in SSR)
84
+ if (src && !loaded && imgRef.current && imgRef.current.complete) {
85
+ setLoaded(true);
86
+ onImageLoaded === null || onImageLoaded === void 0 ? void 0 : onImageLoaded();
87
+ }
82
88
  }, [loaded, src]);
83
89
  const makeInitialsFromName = () => {
84
90
  if (!name || typeof name !== 'string') {
@@ -97,7 +103,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
97
103
  };
98
104
  const handleImageLoaded = event => {
99
105
  setLoaded(true);
100
- onImageLoaded(event);
106
+ onImageLoaded === null || onImageLoaded === void 0 ? void 0 : onImageLoaded(event);
101
107
  };
102
108
  const renderInitials = () => {
103
109
  return _jsx("span", {
@@ -142,6 +148,7 @@ const Avatar = /*#__PURE__*/forwardRef(({
142
148
  children: [_jsx("img", {
143
149
  // This is visually hidden and is here for loading purposes only
144
150
  src: src,
151
+ ref: imgRef,
145
152
  css: styles === null || styles === void 0 ? void 0 : styles.loadImage,
146
153
  alt: alt,
147
154
  onLoad: handleImageLoaded,
@@ -149,5 +156,6 @@ const Avatar = /*#__PURE__*/forwardRef(({
149
156
  }), !loaded && renderContent()]
150
157
  });
151
158
  });
159
+ Avatar.displayName = 'Avatar';
152
160
  export default Avatar;
153
161
  export { Avatar };
@@ -49,7 +49,7 @@ category: components
49
49
  showBorder = 'auto',
50
50
  shape = 'circle',
51
51
  display = 'inline-block',
52
- onImageLoaded = _event => {},
52
+ onImageLoaded,
53
53
  src,
54
54
  name,
55
55
  renderIcon,
@@ -60,6 +60,7 @@ category: components
60
60
  elementRef,
61
61
  ...rest
62
62
  }, ref) => {
63
+ const imgRef = (0, _react.useRef)(null);
63
64
  const _useState = (0, _react.useState)(false),
64
65
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
65
66
  loaded = _useState2[0],
@@ -85,6 +86,11 @@ category: components
85
86
  if (loaded && !src) {
86
87
  setLoaded(false);
87
88
  }
89
+ // Image already loaded (common in SSR)
90
+ if (src && !loaded && imgRef.current && imgRef.current.complete) {
91
+ setLoaded(true);
92
+ onImageLoaded === null || onImageLoaded === void 0 ? void 0 : onImageLoaded();
93
+ }
88
94
  }, [loaded, src]);
89
95
  const makeInitialsFromName = () => {
90
96
  if (!name || typeof name !== 'string') {
@@ -103,7 +109,7 @@ category: components
103
109
  };
104
110
  const handleImageLoaded = event => {
105
111
  setLoaded(true);
106
- onImageLoaded(event);
112
+ onImageLoaded === null || onImageLoaded === void 0 ? void 0 : onImageLoaded(event);
107
113
  };
108
114
  const renderInitials = () => {
109
115
  return (0, _jsxRuntime.jsx)("span", {
@@ -148,6 +154,7 @@ category: components
148
154
  children: [(0, _jsxRuntime.jsx)("img", {
149
155
  // This is visually hidden and is here for loading purposes only
150
156
  src: src,
157
+ ref: imgRef,
151
158
  css: styles === null || styles === void 0 ? void 0 : styles.loadImage,
152
159
  alt: alt,
153
160
  onLoad: handleImageLoaded,
@@ -155,4 +162,5 @@ category: components
155
162
  }), !loaded && renderContent()]
156
163
  });
157
164
  });
165
+ Avatar.displayName = 'Avatar';
158
166
  var _default = exports.default = Avatar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-avatar",
3
- "version": "10.24.3-snapshot-2",
3
+ "version": "10.24.3-snapshot-5",
4
4
  "description": "An image or letters that represents a user.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,19 +24,19 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.27.6",
27
- "@instructure/emotion": "10.24.3-snapshot-2",
28
- "@instructure/shared-types": "10.24.3-snapshot-2",
29
- "@instructure/ui-icons": "10.24.3-snapshot-2",
30
- "@instructure/ui-react-utils": "10.24.3-snapshot-2",
31
- "@instructure/ui-testable": "10.24.3-snapshot-2",
32
- "@instructure/ui-view": "10.24.3-snapshot-2",
27
+ "@instructure/emotion": "10.24.3-snapshot-5",
28
+ "@instructure/shared-types": "10.24.3-snapshot-5",
29
+ "@instructure/ui-icons": "10.24.3-snapshot-5",
30
+ "@instructure/ui-react-utils": "10.24.3-snapshot-5",
31
+ "@instructure/ui-testable": "10.24.3-snapshot-5",
32
+ "@instructure/ui-view": "10.24.3-snapshot-5",
33
33
  "prop-types": "^15.8.1"
34
34
  },
35
35
  "devDependencies": {
36
- "@instructure/ui-axe-check": "10.24.3-snapshot-2",
37
- "@instructure/ui-babel-preset": "10.24.3-snapshot-2",
38
- "@instructure/ui-color-utils": "10.24.3-snapshot-2",
39
- "@instructure/ui-themes": "10.24.3-snapshot-2",
36
+ "@instructure/ui-axe-check": "10.24.3-snapshot-5",
37
+ "@instructure/ui-babel-preset": "10.24.3-snapshot-5",
38
+ "@instructure/ui-color-utils": "10.24.3-snapshot-5",
39
+ "@instructure/ui-themes": "10.24.3-snapshot-5",
40
40
  "@testing-library/jest-dom": "^6.6.3",
41
41
  "@testing-library/react": "^16.0.1",
42
42
  "vitest": "^3.2.2"
@@ -28,7 +28,8 @@ import {
28
28
  SyntheticEvent,
29
29
  useEffect,
30
30
  forwardRef,
31
- ForwardedRef
31
+ ForwardedRef,
32
+ useRef
32
33
  } from 'react'
33
34
 
34
35
  import { View } from '@instructure/ui-view'
@@ -52,7 +53,7 @@ const Avatar = forwardRef(
52
53
  showBorder = 'auto',
53
54
  shape = 'circle',
54
55
  display = 'inline-block',
55
- onImageLoaded = (_event: SyntheticEvent) => {},
56
+ onImageLoaded,
56
57
  src,
57
58
  name,
58
59
  renderIcon,
@@ -65,6 +66,7 @@ const Avatar = forwardRef(
65
66
  }: AvatarProps,
66
67
  ref: ForwardedRef<View>
67
68
  ) => {
69
+ const imgRef = useRef<HTMLImageElement>(null)
68
70
  const [loaded, setLoaded] = useState(false)
69
71
 
70
72
  const styles = useStyle({
@@ -89,6 +91,11 @@ const Avatar = forwardRef(
89
91
  if (loaded && !src) {
90
92
  setLoaded(false)
91
93
  }
94
+ // Image already loaded (common in SSR)
95
+ if (src && !loaded && imgRef.current && imgRef.current.complete) {
96
+ setLoaded(true)
97
+ onImageLoaded?.()
98
+ }
92
99
  }, [loaded, src])
93
100
 
94
101
  const makeInitialsFromName = () => {
@@ -110,7 +117,7 @@ const Avatar = forwardRef(
110
117
 
111
118
  const handleImageLoaded = (event: SyntheticEvent) => {
112
119
  setLoaded(true)
113
- onImageLoaded(event)
120
+ onImageLoaded?.(event)
114
121
  }
115
122
 
116
123
  const renderInitials = () => {
@@ -157,6 +164,7 @@ const Avatar = forwardRef(
157
164
  >
158
165
  <img // This is visually hidden and is here for loading purposes only
159
166
  src={src}
167
+ ref={imgRef}
160
168
  css={styles?.loadImage}
161
169
  alt={alt}
162
170
  onLoad={handleImageLoaded}
@@ -167,6 +175,7 @@ const Avatar = forwardRef(
167
175
  )
168
176
  }
169
177
  )
178
+ Avatar.displayName = 'Avatar'
170
179
 
171
180
  export default Avatar
172
181
  export { Avatar }
@@ -86,9 +86,11 @@ type AvatarOwnProps = {
86
86
  */
87
87
  margin?: Spacing
88
88
  /**
89
- * Callback fired when the avatar image has loaded
89
+ * Callback fired when the avatar image has loaded.
90
+ * `event` can be `undefined`, if its already loaded when the page renders
91
+ * (can happen in SSR)
90
92
  */
91
- onImageLoaded?: (event: SyntheticEvent) => void
93
+ onImageLoaded?: (event?: SyntheticEvent) => void
92
94
  /**
93
95
  * The element type to render as
94
96
  */