Skip to content

Commit

Permalink
[EuiAvatar] Add letter casing prop support and default to capitaliz…
Browse files Browse the repository at this point in the history
…ing initials (#6739)

* [EuiAvatar] Add `casing` prop support and convert default to `capitalize`

* Update avatar docs with new `casing` prop

+ use flex/gap instead of spaces

* changelog

* Update downstream snapshots

* [docs] add snippet

* [PR feedback] Default to `uppercase` for user avatars and `none` for spaces

* Update snapshots

* update changelog
  • Loading branch information
cee-chen authored May 1, 2023
1 parent e7ce298 commit d1ca8b9
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 68 deletions.
2 changes: 2 additions & 0 deletions src-docs/src/views/avatar/avatar_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const avatarInitialsSnippet = [
`<EuiAvatar name="Undefined" initials="?" />
`,
`<EuiAvatar name="Engineering User" initials="En" initialsLength={2} />
`,
`<EuiAvatar name="lower case" casing="capitalize" />
`,
];

Expand Down
44 changes: 26 additions & 18 deletions src-docs/src/views/avatar/avatar_initials.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
import React from 'react';

import { EuiAvatar, EuiTitle, EuiSpacer } from '../../../../src/components';
import {
EuiAvatar,
EuiTitle,
EuiSpacer,
EuiFlexGroup,
} from '../../../../src/components';

export default () => (
<div>
<>
<EuiTitle size="xs">
<h3>Single vs multi-word</h3>
</EuiTitle>
<EuiSpacer />
<EuiAvatar name="Single" />
&emsp;
<EuiAvatar name="Two Words" />
&emsp;
<EuiAvatar name="More Than Two Words" />
&emsp;
<EuiAvatar name="lowercase words" />
<EuiFlexGroup responsive={false} gutterSize="xs">
<EuiAvatar name="Single" />
<EuiAvatar name="Two Words" />
<EuiAvatar name="More Than Two Words" />
<EuiAvatar name="lower case" casing="lowercase" />
</EuiFlexGroup>
<EuiSpacer />
<EuiTitle size="xs">
<h4>Custom</h4>
<h3>Custom</h3>
</EuiTitle>
<EuiSpacer />
<EuiAvatar name="Kibana" initialsLength={2} />
&emsp;
<EuiAvatar name="Leonardo Dude" initialsLength={1} />
&emsp;
<EuiAvatar name="Not provided" initials="?" />
&emsp;
<EuiAvatar name="Engineering User" initials="En" initialsLength={2} />
</div>
<EuiFlexGroup responsive={false} gutterSize="xs">
<EuiAvatar name="Kibana" initialsLength={2} casing="capitalize" />
<EuiAvatar name="Leonardo Dude" initialsLength={1} />
<EuiAvatar name="Not provided" initials="?" />
<EuiAvatar
name="Engineering User"
initials="En"
casing="none"
initialsLength={2}
/>
</EuiFlexGroup>
</>
);
102 changes: 83 additions & 19 deletions src/components/avatar/__snapshots__/avatar.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`EuiAvatar allows a name composed entirely of whitespace 1`] = `
<div
aria-label="aria-label"
class="euiAvatar euiAvatar--m euiAvatar--user testClass1 testClass2 emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user testClass1 testClass2 emotion-euiAvatar-user-m-uppercase"
data-test-subj="test subject string"
role="img"
style="background-color:#ee789d;color:#000000"
Expand All @@ -20,7 +20,7 @@ exports[`EuiAvatar allows a name composed entirely of whitespace 1`] = `
exports[`EuiAvatar is rendered 1`] = `
<div
aria-label="aria-label"
class="euiAvatar euiAvatar--m euiAvatar--user testClass1 testClass2 emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user testClass1 testClass2 emotion-euiAvatar-user-m-uppercase"
data-test-subj="test subject string"
role="img"
style="background-color:#e4a6c7;color:#000000"
Expand All @@ -34,10 +34,74 @@ exports[`EuiAvatar is rendered 1`] = `
</div>
`;

exports[`EuiAvatar props casing capitalize is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-capitalize"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
>
<span
aria-hidden="true"
>
n
</span>
</div>
`;

exports[`EuiAvatar props casing lowercase is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-lowercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
>
<span
aria-hidden="true"
>
n
</span>
</div>
`;

exports[`EuiAvatar props casing none is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-none"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
>
<span
aria-hidden="true"
>
n
</span>
</div>
`;

exports[`EuiAvatar props casing uppercase is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
>
<span
aria-hidden="true"
>
n
</span>
</div>
`;

exports[`EuiAvatar props color as null is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
title="name"
>
Expand All @@ -52,7 +116,7 @@ exports[`EuiAvatar props color as null is rendered 1`] = `
exports[`EuiAvatar props color as plain is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user-plain"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase-plain"
role="img"
title="name"
>
Expand All @@ -67,7 +131,7 @@ exports[`EuiAvatar props color as plain is rendered 1`] = `
exports[`EuiAvatar props color as string is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#000;color:#FFFFFF"
title="name"
Expand All @@ -83,7 +147,7 @@ exports[`EuiAvatar props color as string is rendered 1`] = `
exports[`EuiAvatar props color as subdued is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user-subdued"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase-subdued"
role="img"
title="name"
>
Expand All @@ -98,7 +162,7 @@ exports[`EuiAvatar props color as subdued is rendered 1`] = `
exports[`EuiAvatar props iconType and iconColor as null is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -113,7 +177,7 @@ exports[`EuiAvatar props iconType and iconColor as null is rendered 1`] = `
exports[`EuiAvatar props iconType and iconColor is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -129,7 +193,7 @@ exports[`EuiAvatar props iconType and iconColor is rendered 1`] = `
exports[`EuiAvatar props iconType and iconSize is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -145,7 +209,7 @@ exports[`EuiAvatar props iconType and iconSize is rendered 1`] = `
exports[`EuiAvatar props iconType is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -161,7 +225,7 @@ exports[`EuiAvatar props iconType is rendered 1`] = `
exports[`EuiAvatar props imageUrl is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000;background-image:url(image url)"
title="name"
Expand All @@ -171,7 +235,7 @@ exports[`EuiAvatar props imageUrl is rendered 1`] = `
exports[`EuiAvatar props initials is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -187,7 +251,7 @@ exports[`EuiAvatar props initials is rendered 1`] = `
exports[`EuiAvatar props initialsLength is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -202,7 +266,7 @@ exports[`EuiAvatar props initialsLength is rendered 1`] = `

exports[`EuiAvatar props isDisabled is rendered 1`] = `
<div
class="euiAvatar euiAvatar--m euiAvatar--user euiAvatar-isDisabled emotion-euiAvatar-m-user-isDisabled"
class="euiAvatar euiAvatar--m euiAvatar--user euiAvatar-isDisabled emotion-euiAvatar-user-m-uppercase-isDisabled"
role="presentation"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -218,7 +282,7 @@ exports[`EuiAvatar props isDisabled is rendered 1`] = `
exports[`EuiAvatar props size l is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--l euiAvatar--user emotion-euiAvatar-l-user"
class="euiAvatar euiAvatar--l euiAvatar--user emotion-euiAvatar-user-l-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -234,7 +298,7 @@ exports[`EuiAvatar props size l is rendered 1`] = `
exports[`EuiAvatar props size m is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-m-user"
class="euiAvatar euiAvatar--m euiAvatar--user emotion-euiAvatar-user-m-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -250,7 +314,7 @@ exports[`EuiAvatar props size m is rendered 1`] = `
exports[`EuiAvatar props size s is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--s euiAvatar--user emotion-euiAvatar-s-user"
class="euiAvatar euiAvatar--s euiAvatar--user emotion-euiAvatar-user-s-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -266,7 +330,7 @@ exports[`EuiAvatar props size s is rendered 1`] = `
exports[`EuiAvatar props size xl is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--xl euiAvatar--user emotion-euiAvatar-xl-user"
class="euiAvatar euiAvatar--xl euiAvatar--user emotion-euiAvatar-user-xl-uppercase"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand All @@ -282,7 +346,7 @@ exports[`EuiAvatar props size xl is rendered 1`] = `
exports[`EuiAvatar props type is rendered 1`] = `
<div
aria-label="name"
class="euiAvatar euiAvatar--m euiAvatar--space emotion-euiAvatar-m-space"
class="euiAvatar euiAvatar--m euiAvatar--space emotion-euiAvatar-space-m-none"
role="img"
style="background-color:#e4a6c7;color:#000000"
title="name"
Expand Down
13 changes: 13 additions & 0 deletions src/components/avatar/avatar.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,17 @@ export const euiAvatarStyles = ({ euiTheme }: UseEuiTheme) => ({
fontSize: `calc(${euiTheme.size.xl} * 0.8)`,
})
),
// Casing
capitalize: css`
text-transform: capitalize;
`,
uppercase: css`
text-transform: uppercase;
`,
lowercase: css`
text-transform: lowercase;
`,
none: css`
text-transform: none;
`,
});
12 changes: 11 additions & 1 deletion src/components/avatar/avatar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
import { shouldRenderCustomStyles } from '../../test/internal';

import { EuiAvatar, SIZES } from './avatar';
import { EuiAvatar, SIZES, CASING } from './avatar';

describe('EuiAvatar', () => {
shouldRenderCustomStyles(<EuiAvatar name="name" />);
Expand Down Expand Up @@ -81,6 +81,16 @@ describe('EuiAvatar', () => {
});
});

describe('casing', () => {
CASING.forEach((casing) => {
it(`${casing} is rendered`, () => {
const component = render(<EuiAvatar name="name" casing={casing} />);

expect(component).toMatchSnapshot();
});
});
});

describe('initials', () => {
it('is rendered', () => {
const component = render(<EuiAvatar name="name" initials="lo" />);
Expand Down
18 changes: 16 additions & 2 deletions src/components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export type EuiAvatarSize = typeof SIZES[number];
export const TYPES = ['space', 'user'] as const;
export type EuiAvatarType = typeof TYPES[number];

export const CASING = ['capitalize', 'uppercase', 'lowercase', 'none'] as const;
export type EuiAvatarCasing = typeof CASING[number];

/**
* The avatar can only display one type of content,
* initials, or image, or iconType
Expand Down Expand Up @@ -90,6 +93,14 @@ export type EuiAvatarProps = Omit<HTMLAttributes<HTMLDivElement>, 'color'> &
type?: EuiAvatarType;
size?: EuiAvatarSize;

/**
* Sets the letter casing of the displayed initials.
* Defaults to `uppercase` for `type="user"` avatars.
* Defaults to `none` (uses the existing casing of the passed `name` or `initials`) for `type="space"` avatars.
* @default uppercase
*/
casing?: EuiAvatarCasing;

/**
* Grays out the avatar to simulate being disabled
*/
Expand All @@ -110,8 +121,10 @@ export const EuiAvatar: FunctionComponent<EuiAvatarProps> = ({
type = 'user',
isDisabled = false,
style,
...rest
...props
}) => {
const { casing = type === 'space' ? 'none' : 'uppercase', ...rest } = props;

const euiTheme = useEuiTheme();
const styles = euiAvatarStyles(euiTheme);

Expand All @@ -132,8 +145,9 @@ export const EuiAvatar: FunctionComponent<EuiAvatarProps> = ({

const cssStyles = [
styles.euiAvatar,
styles[size],
styles[type],
styles[size],
styles[casing],
isPlain && styles.plain,
isSubdued && styles.subdued,
isDisabled && styles.isDisabled,
Expand Down
Loading

0 comments on commit d1ca8b9

Please sign in to comment.