@sproutsocial/seeds-react-avatar 1.0.9 → 1.1.0

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.
@@ -8,14 +8,14 @@ $ tsup --dts
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.js 5.68 KB
12
- CJS dist/index.js.map 7.13 KB
13
- CJS ⚡️ Build success in 142ms
14
- ESM dist/esm/index.js 3.57 KB
15
- ESM dist/esm/index.js.map 7.04 KB
16
- ESM ⚡️ Build success in 148ms
11
+ CJS dist/index.js 5.73 KB
12
+ CJS dist/index.js.map 7.22 KB
13
+ CJS ⚡️ Build success in 157ms
14
+ ESM dist/esm/index.js 3.62 KB
15
+ ESM dist/esm/index.js.map 7.13 KB
16
+ ESM ⚡️ Build success in 149ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 24305ms
18
+ DTS ⚡️ Build success in 24562ms
19
19
  DTS dist/index.d.ts 1.65 KB
20
20
  DTS dist/index.d.mts 1.65 KB
21
- Done in 31.81s.
21
+ Done in 31.91s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sproutsocial/seeds-react-avatar
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b147e07: Removing redundant ARIA-related props when components are hidden from screenreaders.
8
+
3
9
  ## 1.0.9
4
10
 
5
11
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -67,6 +67,7 @@ var Avatar = ({
67
67
  setImageFailedLoading(true);
68
68
  }, [setImageFailedLoading]);
69
69
  const fontSize = Math.floor(Number(size.replace("px", "")) * 0.4);
70
+ const ariaProps = { "aria-hidden": ariaHidden, alt: ariaHidden ? "" : name };
70
71
  return /* @__PURE__ */ jsx(
71
72
  Container,
72
73
  {
@@ -97,13 +98,12 @@ var Avatar = ({
97
98
  ) : /* @__PURE__ */ jsx(
98
99
  Image,
99
100
  {
100
- alt: name,
101
+ ...ariaProps,
101
102
  width: "auto",
102
103
  height: "100%",
103
104
  src,
104
105
  onError: handleError,
105
- m: 0,
106
- "aria-hidden": ariaHidden
106
+ m: 0
107
107
  }
108
108
  )
109
109
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Avatar.tsx","../../src/constants.ts","../../src/index.ts"],"sourcesContent":["import { useState, useCallback, useMemo, memo, useEffect } from \"react\";\nimport styled, { css } from \"styled-components\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Image from \"@sproutsocial/seeds-react-image\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type {\n TypeAvatarProps,\n TypeAvatarContainerProps,\n TypeAvatarType,\n} from \"./AvatarTypes\";\n\nimport { BORDER } from \"@sproutsocial/seeds-react-system-props\";\n\nconst defaultType = \"neutral\";\n\nconst AvatarText = styled(({ fontSize, ...rest }) => <Text {...rest} />)`\n font-size: ${(props) => props.fontSize}px;\n color: ${({ theme, type, color }) =>\n color ? color : theme.colors.text.decorative[type]};\n`;\n\nconst Container = styled(Box)<TypeAvatarContainerProps>`\n ${({ theme, $type, bg, borderColor, $displayFallback }) => css`\n background: ${$displayFallback\n ? bg\n ? bg\n : theme.colors.container.background.decorative[$type]\n : \"none\"};\n border: ${$displayFallback ? `1px solid` : \"none\"};\n border-color: ${borderColor\n ? borderColor\n : theme.colors.container.border.decorative[$type]};\n color: ${theme.colors.text.decorative[$type]};\n `}\n\n ${BORDER}\n`;\n\nconst getInitials = (name: string, fallback = \"?\"): string => {\n if (!name || typeof name !== \"string\") return fallback;\n return name\n .replace(/\\s+/, \" \")\n .split(\" \") // Repeated spaces results in empty strings\n .slice(0, 2)\n .map((v) => v && v[0]?.toUpperCase()) // Watch out for empty strings\n .join(\"\");\n};\n\nexport const getAvatarColor = (\n name: string,\n type: TypeAvatarType\n): TypeAvatarType => {\n if (type !== \"auto\") {\n return type;\n }\n\n const colors: Array<TypeAvatarType> = [\n \"purple\",\n \"green\",\n \"blue\",\n \"yellow\",\n \"red\",\n \"orange\",\n ];\n\n // Condense the avatar name down into a number\n const seed = name.split(\"\").reduce((seed, char) => {\n return seed + char.charCodeAt(0);\n }, 0);\n\n // Use that seed modulo the number of available colors to generate\n // a \"random\" color value which will always be consistent\n // for a given string. As a failsafe, return neutral (this should never happen).\n return colors[seed % colors.length] || \"neutral\";\n};\n\nexport const Avatar = ({\n appearance = \"circle\",\n name = \"\",\n src,\n type = defaultType,\n size = \"40px\",\n bg,\n color,\n initials,\n \"aria-hidden\": ariaHidden,\n ...rest\n}: TypeAvatarProps) => {\n const colorType = getAvatarColor(name, type);\n const [imageFailedLoading, setImageFailedLoading] = useState(false);\n\n useEffect(() => {\n // If the src changes, we need to invalidate the image failed to load flag\n setImageFailedLoading(false);\n }, [src]);\n\n const displayInitials = useMemo(\n () => initials || getInitials(name),\n [initials, name]\n );\n const handleError = useCallback(() => {\n setImageFailedLoading(true);\n }, [setImageFailedLoading]);\n\n // Font size for initials is half the size of the avatar, rounded down.\n const fontSize = Math.floor(Number(size.replace(\"px\", \"\")) * 0.4);\n\n return (\n <Container\n size={size}\n overflow=\"hidden\"\n borderRadius={appearance === \"leaf\" ? \"40% 0 40% 0\" : \"50%\"}\n position=\"relative\"\n display=\"flex\"\n flexShrink={0}\n justifyContent=\"center\"\n alignItems=\"center\"\n title={name}\n bg={bg}\n $type={colorType}\n data-qa-user-avatar={name}\n $displayFallback={!src || imageFailedLoading}\n {...rest}\n >\n {!src || imageFailedLoading ? (\n <AvatarText\n lineHeight={size}\n fontWeight=\"semibold\"\n fontSize={fontSize}\n type={colorType}\n color={color}\n >\n {displayInitials}\n </AvatarText>\n ) : (\n <Image\n alt={name}\n width=\"auto\"\n height=\"100%\"\n src={src}\n onError={handleError}\n m={0}\n aria-hidden={ariaHidden}\n />\n )}\n </Container>\n );\n};\n\nexport default memo(Avatar);\n","export const AvatarColorOptions = {\n auto: \"auto\",\n neutral: \"neutral\",\n purple: \"purple\",\n green: \"green\",\n blue: \"blue\",\n yellow: \"yellow\",\n red: \"red\",\n orange: \"orange\",\n} as const;\n","import Avatar from \"./Avatar\";\n\nexport default Avatar;\nexport { Avatar };\nexport * from \"./AvatarTypes\";\nexport { AvatarColorOptions } from \"./constants\";\n"],"mappings":"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","names":["seed"]}
1
+ {"version":3,"sources":["../../src/Avatar.tsx","../../src/constants.ts","../../src/index.ts"],"sourcesContent":["import { useState, useCallback, useMemo, memo, useEffect } from \"react\";\nimport styled, { css } from \"styled-components\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Image from \"@sproutsocial/seeds-react-image\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type {\n TypeAvatarProps,\n TypeAvatarContainerProps,\n TypeAvatarType,\n} from \"./AvatarTypes\";\n\nimport { BORDER } from \"@sproutsocial/seeds-react-system-props\";\n\nconst defaultType = \"neutral\";\n\nconst AvatarText = styled(({ fontSize, ...rest }) => <Text {...rest} />)`\n font-size: ${(props) => props.fontSize}px;\n color: ${({ theme, type, color }) =>\n color ? color : theme.colors.text.decorative[type]};\n`;\n\nconst Container = styled(Box)<TypeAvatarContainerProps>`\n ${({ theme, $type, bg, borderColor, $displayFallback }) => css`\n background: ${$displayFallback\n ? bg\n ? bg\n : theme.colors.container.background.decorative[$type]\n : \"none\"};\n border: ${$displayFallback ? `1px solid` : \"none\"};\n border-color: ${borderColor\n ? borderColor\n : theme.colors.container.border.decorative[$type]};\n color: ${theme.colors.text.decorative[$type]};\n `}\n\n ${BORDER}\n`;\n\nconst getInitials = (name: string, fallback = \"?\"): string => {\n if (!name || typeof name !== \"string\") return fallback;\n return name\n .replace(/\\s+/, \" \")\n .split(\" \") // Repeated spaces results in empty strings\n .slice(0, 2)\n .map((v) => v && v[0]?.toUpperCase()) // Watch out for empty strings\n .join(\"\");\n};\n\nexport const getAvatarColor = (\n name: string,\n type: TypeAvatarType\n): TypeAvatarType => {\n if (type !== \"auto\") {\n return type;\n }\n\n const colors: Array<TypeAvatarType> = [\n \"purple\",\n \"green\",\n \"blue\",\n \"yellow\",\n \"red\",\n \"orange\",\n ];\n\n // Condense the avatar name down into a number\n const seed = name.split(\"\").reduce((seed, char) => {\n return seed + char.charCodeAt(0);\n }, 0);\n\n // Use that seed modulo the number of available colors to generate\n // a \"random\" color value which will always be consistent\n // for a given string. As a failsafe, return neutral (this should never happen).\n return colors[seed % colors.length] || \"neutral\";\n};\n\nexport const Avatar = ({\n appearance = \"circle\",\n name = \"\",\n src,\n type = defaultType,\n size = \"40px\",\n bg,\n color,\n initials,\n \"aria-hidden\": ariaHidden,\n ...rest\n}: TypeAvatarProps) => {\n const colorType = getAvatarColor(name, type);\n const [imageFailedLoading, setImageFailedLoading] = useState(false);\n\n useEffect(() => {\n // If the src changes, we need to invalidate the image failed to load flag\n setImageFailedLoading(false);\n }, [src]);\n\n const displayInitials = useMemo(\n () => initials || getInitials(name),\n [initials, name]\n );\n const handleError = useCallback(() => {\n setImageFailedLoading(true);\n }, [setImageFailedLoading]);\n\n // Font size for initials is half the size of the avatar, rounded down.\n const fontSize = Math.floor(Number(size.replace(\"px\", \"\")) * 0.4);\n\n const ariaProps = { \"aria-hidden\": ariaHidden, alt: ariaHidden ? \"\" : name };\n\n return (\n <Container\n size={size}\n overflow=\"hidden\"\n borderRadius={appearance === \"leaf\" ? \"40% 0 40% 0\" : \"50%\"}\n position=\"relative\"\n display=\"flex\"\n flexShrink={0}\n justifyContent=\"center\"\n alignItems=\"center\"\n title={name}\n bg={bg}\n $type={colorType}\n data-qa-user-avatar={name}\n $displayFallback={!src || imageFailedLoading}\n {...rest}\n >\n {!src || imageFailedLoading ? (\n <AvatarText\n lineHeight={size}\n fontWeight=\"semibold\"\n fontSize={fontSize}\n type={colorType}\n color={color}\n >\n {displayInitials}\n </AvatarText>\n ) : (\n <Image\n {...ariaProps}\n width=\"auto\"\n height=\"100%\"\n src={src}\n onError={handleError}\n m={0}\n />\n )}\n </Container>\n );\n};\n\nexport default memo(Avatar);\n","export const AvatarColorOptions = {\n auto: \"auto\",\n neutral: \"neutral\",\n purple: \"purple\",\n green: \"green\",\n blue: \"blue\",\n yellow: \"yellow\",\n red: \"red\",\n orange: \"orange\",\n} as const;\n","import Avatar from \"./Avatar\";\n\nexport default Avatar;\nexport { Avatar };\nexport * from \"./AvatarTypes\";\nexport { AvatarColorOptions } from \"./constants\";\n"],"mappings":"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","names":["seed"]}
package/dist/index.js CHANGED
@@ -105,6 +105,7 @@ var Avatar = ({
105
105
  setImageFailedLoading(true);
106
106
  }, [setImageFailedLoading]);
107
107
  const fontSize = Math.floor(Number(size.replace("px", "")) * 0.4);
108
+ const ariaProps = { "aria-hidden": ariaHidden, alt: ariaHidden ? "" : name };
108
109
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
109
110
  Container,
110
111
  {
@@ -135,13 +136,12 @@ var Avatar = ({
135
136
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
136
137
  import_seeds_react_image.default,
137
138
  {
138
- alt: name,
139
+ ...ariaProps,
139
140
  width: "auto",
140
141
  height: "100%",
141
142
  src,
142
143
  onError: handleError,
143
- m: 0,
144
- "aria-hidden": ariaHidden
144
+ m: 0
145
145
  }
146
146
  )
147
147
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Avatar.tsx","../src/constants.ts"],"sourcesContent":["import Avatar from \"./Avatar\";\n\nexport default Avatar;\nexport { Avatar };\nexport * from \"./AvatarTypes\";\nexport { AvatarColorOptions } from \"./constants\";\n","import { useState, useCallback, useMemo, memo, useEffect } from \"react\";\nimport styled, { css } from \"styled-components\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Image from \"@sproutsocial/seeds-react-image\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type {\n TypeAvatarProps,\n TypeAvatarContainerProps,\n TypeAvatarType,\n} from \"./AvatarTypes\";\n\nimport { BORDER } from \"@sproutsocial/seeds-react-system-props\";\n\nconst defaultType = \"neutral\";\n\nconst AvatarText = styled(({ fontSize, ...rest }) => <Text {...rest} />)`\n font-size: ${(props) => props.fontSize}px;\n color: ${({ theme, type, color }) =>\n color ? color : theme.colors.text.decorative[type]};\n`;\n\nconst Container = styled(Box)<TypeAvatarContainerProps>`\n ${({ theme, $type, bg, borderColor, $displayFallback }) => css`\n background: ${$displayFallback\n ? bg\n ? bg\n : theme.colors.container.background.decorative[$type]\n : \"none\"};\n border: ${$displayFallback ? `1px solid` : \"none\"};\n border-color: ${borderColor\n ? borderColor\n : theme.colors.container.border.decorative[$type]};\n color: ${theme.colors.text.decorative[$type]};\n `}\n\n ${BORDER}\n`;\n\nconst getInitials = (name: string, fallback = \"?\"): string => {\n if (!name || typeof name !== \"string\") return fallback;\n return name\n .replace(/\\s+/, \" \")\n .split(\" \") // Repeated spaces results in empty strings\n .slice(0, 2)\n .map((v) => v && v[0]?.toUpperCase()) // Watch out for empty strings\n .join(\"\");\n};\n\nexport const getAvatarColor = (\n name: string,\n type: TypeAvatarType\n): TypeAvatarType => {\n if (type !== \"auto\") {\n return type;\n }\n\n const colors: Array<TypeAvatarType> = [\n \"purple\",\n \"green\",\n \"blue\",\n \"yellow\",\n \"red\",\n \"orange\",\n ];\n\n // Condense the avatar name down into a number\n const seed = name.split(\"\").reduce((seed, char) => {\n return seed + char.charCodeAt(0);\n }, 0);\n\n // Use that seed modulo the number of available colors to generate\n // a \"random\" color value which will always be consistent\n // for a given string. As a failsafe, return neutral (this should never happen).\n return colors[seed % colors.length] || \"neutral\";\n};\n\nexport const Avatar = ({\n appearance = \"circle\",\n name = \"\",\n src,\n type = defaultType,\n size = \"40px\",\n bg,\n color,\n initials,\n \"aria-hidden\": ariaHidden,\n ...rest\n}: TypeAvatarProps) => {\n const colorType = getAvatarColor(name, type);\n const [imageFailedLoading, setImageFailedLoading] = useState(false);\n\n useEffect(() => {\n // If the src changes, we need to invalidate the image failed to load flag\n setImageFailedLoading(false);\n }, [src]);\n\n const displayInitials = useMemo(\n () => initials || getInitials(name),\n [initials, name]\n );\n const handleError = useCallback(() => {\n setImageFailedLoading(true);\n }, [setImageFailedLoading]);\n\n // Font size for initials is half the size of the avatar, rounded down.\n const fontSize = Math.floor(Number(size.replace(\"px\", \"\")) * 0.4);\n\n return (\n <Container\n size={size}\n overflow=\"hidden\"\n borderRadius={appearance === \"leaf\" ? \"40% 0 40% 0\" : \"50%\"}\n position=\"relative\"\n display=\"flex\"\n flexShrink={0}\n justifyContent=\"center\"\n alignItems=\"center\"\n title={name}\n bg={bg}\n $type={colorType}\n data-qa-user-avatar={name}\n $displayFallback={!src || imageFailedLoading}\n {...rest}\n >\n {!src || imageFailedLoading ? (\n <AvatarText\n lineHeight={size}\n fontWeight=\"semibold\"\n fontSize={fontSize}\n type={colorType}\n color={color}\n >\n {displayInitials}\n </AvatarText>\n ) : (\n <Image\n alt={name}\n width=\"auto\"\n height=\"100%\"\n src={src}\n onError={handleError}\n m={0}\n aria-hidden={ariaHidden}\n />\n )}\n </Container>\n );\n};\n\nexport default memo(Avatar);\n","export const AvatarColorOptions = {\n auto: \"auto\",\n neutral: \"neutral\",\n purple: \"purple\",\n green: \"green\",\n blue: \"blue\",\n yellow: \"yellow\",\n red: \"red\",\n orange: \"orange\",\n} as const;\n"],"mappings":"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","names":["styled","Text","Box","seed","Image"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Avatar.tsx","../src/constants.ts"],"sourcesContent":["import Avatar from \"./Avatar\";\n\nexport default Avatar;\nexport { Avatar };\nexport * from \"./AvatarTypes\";\nexport { AvatarColorOptions } from \"./constants\";\n","import { useState, useCallback, useMemo, memo, useEffect } from \"react\";\nimport styled, { css } from \"styled-components\";\n\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Image from \"@sproutsocial/seeds-react-image\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport type {\n TypeAvatarProps,\n TypeAvatarContainerProps,\n TypeAvatarType,\n} from \"./AvatarTypes\";\n\nimport { BORDER } from \"@sproutsocial/seeds-react-system-props\";\n\nconst defaultType = \"neutral\";\n\nconst AvatarText = styled(({ fontSize, ...rest }) => <Text {...rest} />)`\n font-size: ${(props) => props.fontSize}px;\n color: ${({ theme, type, color }) =>\n color ? color : theme.colors.text.decorative[type]};\n`;\n\nconst Container = styled(Box)<TypeAvatarContainerProps>`\n ${({ theme, $type, bg, borderColor, $displayFallback }) => css`\n background: ${$displayFallback\n ? bg\n ? bg\n : theme.colors.container.background.decorative[$type]\n : \"none\"};\n border: ${$displayFallback ? `1px solid` : \"none\"};\n border-color: ${borderColor\n ? borderColor\n : theme.colors.container.border.decorative[$type]};\n color: ${theme.colors.text.decorative[$type]};\n `}\n\n ${BORDER}\n`;\n\nconst getInitials = (name: string, fallback = \"?\"): string => {\n if (!name || typeof name !== \"string\") return fallback;\n return name\n .replace(/\\s+/, \" \")\n .split(\" \") // Repeated spaces results in empty strings\n .slice(0, 2)\n .map((v) => v && v[0]?.toUpperCase()) // Watch out for empty strings\n .join(\"\");\n};\n\nexport const getAvatarColor = (\n name: string,\n type: TypeAvatarType\n): TypeAvatarType => {\n if (type !== \"auto\") {\n return type;\n }\n\n const colors: Array<TypeAvatarType> = [\n \"purple\",\n \"green\",\n \"blue\",\n \"yellow\",\n \"red\",\n \"orange\",\n ];\n\n // Condense the avatar name down into a number\n const seed = name.split(\"\").reduce((seed, char) => {\n return seed + char.charCodeAt(0);\n }, 0);\n\n // Use that seed modulo the number of available colors to generate\n // a \"random\" color value which will always be consistent\n // for a given string. As a failsafe, return neutral (this should never happen).\n return colors[seed % colors.length] || \"neutral\";\n};\n\nexport const Avatar = ({\n appearance = \"circle\",\n name = \"\",\n src,\n type = defaultType,\n size = \"40px\",\n bg,\n color,\n initials,\n \"aria-hidden\": ariaHidden,\n ...rest\n}: TypeAvatarProps) => {\n const colorType = getAvatarColor(name, type);\n const [imageFailedLoading, setImageFailedLoading] = useState(false);\n\n useEffect(() => {\n // If the src changes, we need to invalidate the image failed to load flag\n setImageFailedLoading(false);\n }, [src]);\n\n const displayInitials = useMemo(\n () => initials || getInitials(name),\n [initials, name]\n );\n const handleError = useCallback(() => {\n setImageFailedLoading(true);\n }, [setImageFailedLoading]);\n\n // Font size for initials is half the size of the avatar, rounded down.\n const fontSize = Math.floor(Number(size.replace(\"px\", \"\")) * 0.4);\n\n const ariaProps = { \"aria-hidden\": ariaHidden, alt: ariaHidden ? \"\" : name };\n\n return (\n <Container\n size={size}\n overflow=\"hidden\"\n borderRadius={appearance === \"leaf\" ? \"40% 0 40% 0\" : \"50%\"}\n position=\"relative\"\n display=\"flex\"\n flexShrink={0}\n justifyContent=\"center\"\n alignItems=\"center\"\n title={name}\n bg={bg}\n $type={colorType}\n data-qa-user-avatar={name}\n $displayFallback={!src || imageFailedLoading}\n {...rest}\n >\n {!src || imageFailedLoading ? (\n <AvatarText\n lineHeight={size}\n fontWeight=\"semibold\"\n fontSize={fontSize}\n type={colorType}\n color={color}\n >\n {displayInitials}\n </AvatarText>\n ) : (\n <Image\n {...ariaProps}\n width=\"auto\"\n height=\"100%\"\n src={src}\n onError={handleError}\n m={0}\n />\n )}\n </Container>\n );\n};\n\nexport default memo(Avatar);\n","export const AvatarColorOptions = {\n auto: \"auto\",\n neutral: \"neutral\",\n purple: \"purple\",\n green: \"green\",\n blue: \"blue\",\n yellow: \"yellow\",\n red: \"red\",\n orange: \"orange\",\n} as const;\n"],"mappings":"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","names":["styled","Text","Box","seed","Image"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-avatar",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "Seeds React Avatar",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
package/src/Avatar.tsx CHANGED
@@ -106,6 +106,8 @@ export const Avatar = ({
106
106
  // Font size for initials is half the size of the avatar, rounded down.
107
107
  const fontSize = Math.floor(Number(size.replace("px", "")) * 0.4);
108
108
 
109
+ const ariaProps = { "aria-hidden": ariaHidden, alt: ariaHidden ? "" : name };
110
+
109
111
  return (
110
112
  <Container
111
113
  size={size}
@@ -135,13 +137,12 @@ export const Avatar = ({
135
137
  </AvatarText>
136
138
  ) : (
137
139
  <Image
138
- alt={name}
140
+ {...ariaProps}
139
141
  width="auto"
140
142
  height="100%"
141
143
  src={src}
142
144
  onError={handleError}
143
145
  m={0}
144
- aria-hidden={ariaHidden}
145
146
  />
146
147
  )}
147
148
  </Container>