diff --git a/packages/circuit-ui/components/Avatar/Avatar.stories.tsx b/packages/circuit-ui/components/Avatar/Avatar.stories.tsx
index bdb6025488..201e5b7e1b 100644
--- a/packages/circuit-ui/components/Avatar/Avatar.stories.tsx
+++ b/packages/circuit-ui/components/Avatar/Avatar.stories.tsx
@@ -27,7 +27,8 @@ export default {
docs: { page: docs },
},
argTypes: {
- imageUrl: { control: 'text' },
+ src: { control: 'text' },
+ alt: { control: 'text' },
variant: { control: { type: 'radio', options: ['business', 'person'] } },
size: { control: { type: 'radio', options: ['yotta', 'giga'] } },
},
@@ -35,7 +36,8 @@ export default {
export const base = (args: AvatarProps): JSX.Element => ;
base.args = {
- imageUrl: 'https://upload.wikimedia.org/wikipedia/en/8/86/Avatar_Aang.png',
+ src: 'https://upload.wikimedia.org/wikipedia/en/8/86/Avatar_Aang.png',
+ alt: '',
variant: 'person',
size: 'yotta',
};
@@ -45,12 +47,14 @@ export const sizes = (): JSX.Element => (
);
@@ -59,9 +63,10 @@ export const identity = (): JSX.Element => (
-
+
);
@@ -69,8 +74,9 @@ export const object = (): JSX.Element => (
-
+
);
diff --git a/packages/circuit-ui/components/Avatar/Avatar.tsx b/packages/circuit-ui/components/Avatar/Avatar.tsx
index 5569d3b3fb..bfbd597da4 100644
--- a/packages/circuit-ui/components/Avatar/Avatar.tsx
+++ b/packages/circuit-ui/components/Avatar/Avatar.tsx
@@ -13,18 +13,21 @@
* limitations under the License.
*/
-import { HTMLAttributes } from 'react';
+import React, { HTMLAttributes } from 'react';
import { css } from '@emotion/core';
import isPropValid from '@emotion/is-prop-valid';
import styled, { StyleProps } from '../../styles/styled';
-export interface AvatarProps
- extends Omit, 'size'> {
+export interface AvatarProps extends HTMLAttributes {
/**
- * The URL of the Avatar image
+ * The Avatar image source
*/
- imageUrl?: string;
+ src?: string;
+ /**
+ * Alt text for the Avatar
+ */
+ alt: string;
/**
* The variant of the Avatar, either representing a person or a business
*/
@@ -33,15 +36,6 @@ export interface AvatarProps
* The size of the Avatar
*/
size?: 'giga' | 'yotta';
- /**
- * Alternative DOM element to render
- */
- as?: 'label';
- /**
- * htmlFor when the element is a label
- * TODO the element should extend either a div or a label
- */
- htmlFor?: string;
}
const avatarSizes = {
@@ -54,34 +48,44 @@ const placeholders = {
business: ``,
};
+type StyledImageProps = Omit & {
+ variant: 'person' | 'business';
+ size: 'giga' | 'yotta';
+};
+
const baseStyles = ({
theme,
- imageUrl,
- variant = 'person',
- size = 'yotta',
-}: AvatarProps & StyleProps) => css`
+ variant,
+ size,
+}: StyledImageProps & StyleProps) => css`
display: block;
width: ${avatarSizes[size]};
height: ${avatarSizes[size]};
- box-shadow: inset 0 0 0 ${theme.borderWidth.kilo} rgba(0, 0, 0, 0.1);
+ box-shadow: 0 0 0 ${theme.borderWidth.kilo} rgba(0, 0, 0, 0.1);
+ background-color: ${theme.colors.n300};
border-radius: ${variant === 'person'
? theme.borderRadius.circle
: theme.borderRadius.tera};
- border: none;
- background-color: ${theme.colors.n300};
- background-size: cover;
- background-position: center;
- background-image: url('data:image/svg+xml;utf8,${placeholders[variant]}');
-
- ${imageUrl &&
- css`
- background-image: url(${imageUrl});
- `};
+ object-fit: cover;
+ object-position: center;
`;
+const StyledImage = styled('img', {
+ shouldForwardProp: (prop) => isPropValid(prop),
+})(baseStyles);
+
/**
* The Avatar component.
*/
-export const Avatar = styled('div', {
- shouldForwardProp: (prop) => isPropValid(prop),
-})(baseStyles);
+export const Avatar = ({
+ src: initialSrc,
+ alt = '',
+ variant = 'person',
+ size = 'yotta',
+ ...props
+}: AvatarProps): JSX.Element => {
+ const src = initialSrc || `data:image/svg+xml;utf8,${placeholders[variant]}`;
+ return (
+
+ );
+};
diff --git a/packages/circuit-ui/components/ImageInput/ImageInput.tsx b/packages/circuit-ui/components/ImageInput/ImageInput.tsx
index 7802e2932f..34e6ec5600 100644
--- a/packages/circuit-ui/components/ImageInput/ImageInput.tsx
+++ b/packages/circuit-ui/components/ImageInput/ImageInput.tsx
@@ -18,6 +18,7 @@ import { ChangeEvent, Fragment, InputHTMLAttributes, useState } from 'react';
import { css, jsx } from '@emotion/core';
import Avatar from '../Avatar';
+import Label from '../Label';
import styled from '../../styles/styled';
import { uniqueId } from '../../util/id';
import { focusOutline, hideVisually } from '../../styles/style-mixins';
@@ -28,6 +29,10 @@ export interface ImageInputProps
* label
*/
label: string;
+ /**
+ * alt
+ */
+ alt: string;
/**
* imageUrl
*/
@@ -40,12 +45,12 @@ const Input = styled.input(
&:focus + label {
${focusOutline({ theme })};
- border-color: ${theme.colors.p500};
+ border-radius: ${theme.borderRadius.tera};
}
`,
);
-const Image = styled(Avatar)`
+const StyledAvatar = styled(Avatar)`
:hover {
filter: brightness(90%);
cursor: pointer;
@@ -58,6 +63,7 @@ const Image = styled(Avatar)`
export const ImageInput = ({
label,
imageUrl: initialImageUrl,
+ alt,
id: customId,
...props
}: ImageInputProps): JSX.Element => {
@@ -74,16 +80,17 @@ export const ImageInput = ({
return (
-
-
+ />
+
+
+
);
};