From e2d65c97132bf55b166bdd8d456122388876c1a2 Mon Sep 17 00:00:00 2001 From: cchaos Date: Thu, 4 Mar 2021 15:11:41 -0500 Subject: [PATCH 01/10] Update Avatar example docs with more sections --- src-docs/src/views/avatar/avatar_disabled.js | 32 ++++++ src-docs/src/views/avatar/avatar_example.js | 107 ++++++++++++++++++- src-docs/src/views/avatar/avatar_icon.js | 31 ++++++ src-docs/src/views/avatar/avatar_initials.js | 53 ++------- src-docs/src/views/avatar/avatar_type.js | 21 ++++ 5 files changed, 197 insertions(+), 47 deletions(-) create mode 100644 src-docs/src/views/avatar/avatar_disabled.js create mode 100644 src-docs/src/views/avatar/avatar_icon.js create mode 100644 src-docs/src/views/avatar/avatar_type.js diff --git a/src-docs/src/views/avatar/avatar_disabled.js b/src-docs/src/views/avatar/avatar_disabled.js new file mode 100644 index 00000000000..2fb0b4dc3b0 --- /dev/null +++ b/src-docs/src/views/avatar/avatar_disabled.js @@ -0,0 +1,32 @@ +import React from 'react'; + +import { EuiAvatar } from '../../../../src/components'; + +export default () => ( +
+ +   + +   + +
+); diff --git a/src-docs/src/views/avatar/avatar_example.js b/src-docs/src/views/avatar/avatar_example.js index b6d553cd8bd..2c7e23de66b 100644 --- a/src-docs/src/views/avatar/avatar_example.js +++ b/src-docs/src/views/avatar/avatar_example.js @@ -29,6 +29,42 @@ const avatarInitialsSnippet = [ `, ]; +import AvatarTypes from './avatar_type'; +const avatarTypesSource = require('!!raw-loader!./avatar_type'); +const avatarTypesHtml = renderToHtml(AvatarTypes); +const avatarTypesSnippet = [ + ` +`, + ` +`, + ` +`, +]; + +import AvatarIcons from './avatar_icon'; +const avatarIconsSource = require('!!raw-loader!./avatar_icon'); +const avatarIconsHtml = renderToHtml(AvatarIcons); +const avatarIconsSnippet = [ + ` +`, + ` +`, + ` +`, +]; + +import AvatarDisabled from './avatar_disabled'; +const avatarDisabledSource = require('!!raw-loader!./avatar_disabled'); +const avatarDisabledHtml = renderToHtml(AvatarDisabled); +const avatarDisabledSnippet = [ + ` +`, + ` +`, + ` +`, +]; + export const AvatarExample = { title: 'Avatar', sections: [ @@ -83,7 +119,25 @@ export const AvatarExample = { props. However, the avatar will still always max out at 2 characters.

-

Types

+ + ), + snippet: avatarInitialsSnippet, + demo: , + }, + { + title: 'Types', + source: [ + { + type: GuideSectionTypes.JS, + code: avatarTypesSource, + }, + { + type: GuideSectionTypes.HTML, + code: avatarTypesHtml, + }, + ], + text: ( +

The avatar type, which primarily defines the shape, is keyworded and can be{' '} @@ -92,8 +146,55 @@ export const AvatarExample = {

), - snippet: avatarInitialsSnippet, - demo: , + snippet: avatarTypesSnippet, + demo: , + }, + { + title: 'Icons', + source: [ + { + type: GuideSectionTypes.JS, + code: avatarIconsSource, + }, + { + type: GuideSectionTypes.HTML, + code: avatarIconsHtml, + }, + ], + text: ( +
+

+ Icons can also be used within avatars and will be sized + appropriately. +

+
+ ), + snippet: avatarIconsSnippet, + demo: , + }, + { + title: 'Disabled', + source: [ + { + type: GuideSectionTypes.JS, + code: avatarDisabledSource, + }, + { + type: GuideSectionTypes.HTML, + code: avatarDisabledHtml, + }, + ], + text: ( +
+

+ While EuiAvatar doesn't accept any interactive behaviors + themselves. You can ensure a visual change if placed within a + disabled element by passing the disabled prop. +

+
+ ), + snippet: avatarDisabledSnippet, + demo: , }, ], playground: avatarConfig, diff --git a/src-docs/src/views/avatar/avatar_icon.js b/src-docs/src/views/avatar/avatar_icon.js new file mode 100644 index 00000000000..4d7ffde093f --- /dev/null +++ b/src-docs/src/views/avatar/avatar_icon.js @@ -0,0 +1,31 @@ +import React from 'react'; + +import { EuiAvatar } from '../../../../src/components'; + +export default () => ( +
+ +   + +   + +   + +
+); diff --git a/src-docs/src/views/avatar/avatar_initials.js b/src-docs/src/views/avatar/avatar_initials.js index 6c92d30d662..3a08775abb0 100644 --- a/src-docs/src/views/avatar/avatar_initials.js +++ b/src-docs/src/views/avatar/avatar_initials.js @@ -8,59 +8,24 @@ export default () => (

Single vs multi-word

- +   - +   - +   - + -

Custom & Spaces type

+

Custom

- +   - +   - +   - - - -

Disabled

-
- - -   - -   - + ); diff --git a/src-docs/src/views/avatar/avatar_type.js b/src-docs/src/views/avatar/avatar_type.js new file mode 100644 index 00000000000..ebff90d87ef --- /dev/null +++ b/src-docs/src/views/avatar/avatar_type.js @@ -0,0 +1,21 @@ +import React from 'react'; + +import { EuiAvatar } from '../../../../src/components'; + +export default () => ( +
+ +   + +   + +   + +
+); From 2b60ff92a42333b57b94976ba095171df21a4b94 Mon Sep 17 00:00:00 2001 From: cchaos Date: Thu, 4 Mar 2021 16:58:43 -0500 Subject: [PATCH 02/10] Updated the content types to be exclusive between `initials`, `imageUrl`, or `iconType` Also updated layout to use inline-flex, and made background-image `undefined` instead of `none` --- src-docs/src/views/avatar/avatar_icon.js | 24 +----- .../avatar/__snapshots__/avatar.test.tsx.snap | 52 ++++++------- src/components/avatar/_avatar.scss | 4 +- src/components/avatar/avatar.test.tsx | 8 ++ src/components/avatar/avatar.tsx | 74 +++++++++++++------ .../__snapshots__/comment.test.tsx.snap | 2 +- .../comment_timeline.test.tsx.snap | 2 +- .../__snapshots__/popover.test.tsx.snap | 2 +- 8 files changed, 97 insertions(+), 71 deletions(-) diff --git a/src-docs/src/views/avatar/avatar_icon.js b/src-docs/src/views/avatar/avatar_icon.js index 4d7ffde093f..f7dcc001d05 100644 --- a/src-docs/src/views/avatar/avatar_icon.js +++ b/src-docs/src/views/avatar/avatar_icon.js @@ -4,28 +4,12 @@ import { EuiAvatar } from '../../../../src/components'; export default () => (
- +   - +   - +   - +
); diff --git a/src/components/avatar/__snapshots__/avatar.test.tsx.snap b/src/components/avatar/__snapshots__/avatar.test.tsx.snap index 78d9b025151..e65d86be680 100644 --- a/src/components/avatar/__snapshots__/avatar.test.tsx.snap +++ b/src/components/avatar/__snapshots__/avatar.test.tsx.snap @@ -5,7 +5,7 @@ exports[`EuiAvatar allows a name composed entirely of whitespace 1`] = ` aria-label="aria-label" class="euiAvatar euiAvatar--m euiAvatar--user testClass1 testClass2" data-test-subj="test subject string" - style="background-image:none;background-color:#ee789d;color:#000000" + style="background-color:#ee789d;color:#000000" title=" " > `; +exports[`EuiAvatar props iconType is rendered 1`] = ` +
+ +
+`; + exports[`EuiAvatar props imageUrl is rendered 1`] = `
- -
-`; - -exports[`EuiAvatar props size none is rendered 1`] = ` -
{ }); }); + describe('iconType', () => { + it('is rendered', () => { + const component = render(); + + expect(component).toMatchSnapshot(); + }); + }); + describe('size', () => { SIZES.forEach((size) => { it(`${size} is rendered`, () => { diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx index 6e00ca2ed4b..0c421a4c1ba 100644 --- a/src/components/avatar/avatar.tsx +++ b/src/components/avatar/avatar.tsx @@ -18,14 +18,14 @@ */ import React, { HTMLAttributes, FunctionComponent } from 'react'; -import { CommonProps, keysOf } from '../common'; +import { CommonProps, ExclusiveUnion, keysOf } from '../common'; import classNames from 'classnames'; import { isColorDark, hexToRgb, isValidHex } from '../../services/color'; import { euiPaletteColorBlindBehindText, toInitials } from '../../services'; +import { IconType, EuiIcon } from '../icon'; const sizeToClassNameMap = { - none: null, s: 'euiAvatar--s', m: 'euiAvatar--m', l: 'euiAvatar--l', @@ -43,8 +43,43 @@ const typeToClassNameMap = { export const TYPES = keysOf(typeToClassNameMap); export type EuiAvatarType = keyof typeof typeToClassNameMap; +/** + * The avatar can only display one type of content, + * initials, or image, or iconType + */ +type _EuiAvatarContent = ExclusiveUnion< + ExclusiveUnion< + { + /** + * Custom initials (max 2 characters). + * By default will take the first character (of each word). + */ + initials?: string; + + /** + * Specify how many characters to show (1 or 2). + * By default, will show based on number of words (max first 2). + */ + initialsLength?: 1 | 2; + }, + { + /** + * Path to an image to dispaly instead of initials + */ + imageUrl?: string; + } + >, + { + /** + * Any EUI glyph, logo or custom icon to display instead of initials + */ + iconType?: IconType; + } +>; + export type EuiAvatarProps = Omit, 'color'> & - CommonProps & { + CommonProps & + _EuiAvatarContent & { /** * Full name of avatar for title attribute and calculating initial if not provided */ @@ -55,23 +90,10 @@ export type EuiAvatarProps = Omit, 'color'> & */ color?: string; - /** - * Custom initials (max 2 characters). - * By default will take the first character (of each word). - */ - initials?: string; - - /** - * Specify how many characters to show (max 2 allowed). - * By default, will show based on number of words. - */ - initialsLength?: 1 | 2; - /** * The type of avatar this is displaying */ type?: EuiAvatarType; - imageUrl?: string; size?: EuiAvatarSize; /** @@ -86,6 +108,7 @@ export const EuiAvatar: FunctionComponent = ({ imageUrl, initials, initialsLength, + iconType, name, size = 'm', type = 'user', @@ -107,11 +130,20 @@ export const EuiAvatar: FunctionComponent = ({ checkValidColor(color); checkValidInitials(initials); - let optionalInitial; - if (name && !imageUrl) { + let content; + if (!imageUrl && !iconType) { // Create the initials const calculatedInitials = toInitials(name, initialsLength, initials); - optionalInitial = ; + content = ; + } else if (iconType) { + content = ( + + ); } const assignedColor = @@ -121,7 +153,7 @@ export const EuiAvatar: FunctionComponent = ({ : '#000000'; const avatarStyle = { - backgroundImage: imageUrl ? `url(${imageUrl})` : 'none', + backgroundImage: imageUrl ? `url(${imageUrl})` : undefined, backgroundColor: assignedColor, color: textColor, }; @@ -133,7 +165,7 @@ export const EuiAvatar: FunctionComponent = ({ aria-label={name} title={name} {...rest}> - {optionalInitial} + {content}
); }; diff --git a/src/components/comment_list/__snapshots__/comment.test.tsx.snap b/src/components/comment_list/__snapshots__/comment.test.tsx.snap index c4cd24693e3..b88c7f7f046 100644 --- a/src/components/comment_list/__snapshots__/comment.test.tsx.snap +++ b/src/components/comment_list/__snapshots__/comment.test.tsx.snap @@ -104,7 +104,7 @@ exports[`EuiComment props timelineIcon is rendered 1`] = `
Date: Thu, 4 Mar 2021 17:50:01 -0500 Subject: [PATCH 03/10] Added `iconSize` and `iconColor` overrides Updating all docs sections and snippets --- src-docs/src/views/avatar/avatar_disabled.js | 7 +++ src-docs/src/views/avatar/avatar_example.js | 50 +++++++++++-------- src-docs/src/views/avatar/avatar_icon.js | 41 +++++++++++++-- src-docs/src/views/avatar/avatar_type.js | 20 ++++---- .../avatar/__snapshots__/avatar.test.tsx.snap | 48 ++++++++++++++++++ src/components/avatar/avatar.test.tsx | 24 +++++++++ src/components/avatar/avatar.tsx | 44 ++++++++++------ 7 files changed, 183 insertions(+), 51 deletions(-) diff --git a/src-docs/src/views/avatar/avatar_disabled.js b/src-docs/src/views/avatar/avatar_disabled.js index 2fb0b4dc3b0..5953a39e302 100644 --- a/src-docs/src/views/avatar/avatar_disabled.js +++ b/src-docs/src/views/avatar/avatar_disabled.js @@ -28,5 +28,12 @@ export default () => ( imageUrl="https://source.unsplash.com/64x64/?cat" isDisabled={true} /> +   +
); diff --git a/src-docs/src/views/avatar/avatar_example.js b/src-docs/src/views/avatar/avatar_example.js index 2c7e23de66b..c80c1d45a82 100644 --- a/src-docs/src/views/avatar/avatar_example.js +++ b/src-docs/src/views/avatar/avatar_example.js @@ -11,21 +11,22 @@ import Avatar from './avatar'; const avatarSource = require('!!raw-loader!./avatar'); const avatarHtml = renderToHtml(Avatar); const avatarSnippet = [ - ` + ` `, ` `, + '', ]; import AvatarInitials from './avatar_initials'; const avatarInitialsSource = require('!!raw-loader!./avatar_initials'); const avatarInitialsHtml = renderToHtml(AvatarInitials); const avatarInitialsSnippet = [ - ` + ` `, - ` + ` `, - ` + ` `, ]; @@ -33,11 +34,7 @@ import AvatarTypes from './avatar_type'; const avatarTypesSource = require('!!raw-loader!./avatar_type'); const avatarTypesHtml = renderToHtml(AvatarTypes); const avatarTypesSnippet = [ - ` -`, - ` -`, - ` + ` `, ]; @@ -45,11 +42,11 @@ import AvatarIcons from './avatar_icon'; const avatarIconsSource = require('!!raw-loader!./avatar_icon'); const avatarIconsHtml = renderToHtml(AvatarIcons); const avatarIconsSnippet = [ - ` + ` `, - ` + ` `, - ` + ` `, ]; @@ -57,11 +54,7 @@ import AvatarDisabled from './avatar_disabled'; const avatarDisabledSource = require('!!raw-loader!./avatar_disabled'); const avatarDisabledHtml = renderToHtml(AvatarDisabled); const avatarDisabledSnippet = [ - ` -`, - ` -`, - ` + ` `, ]; @@ -82,8 +75,8 @@ export const AvatarExample = { text: (

- The EuiAvatar component creates a user icon. It - will accept name (required) and{' '} + The EuiAvatar component typically creates a user + icon. It will accept name (required) and{' '} image props and will configure the display and accessibility as needed. By default, the background colors come from the set of colors used for visualizations. Otherwise you can pass a @@ -123,6 +116,7 @@ export const AvatarExample = { ), snippet: avatarInitialsSnippet, demo: , + props: { EuiAvatar }, }, { title: 'Types', @@ -148,6 +142,7 @@ export const AvatarExample = { ), snippet: avatarTypesSnippet, demo: , + props: { EuiAvatar }, }, { title: 'Icons', @@ -164,13 +159,25 @@ export const AvatarExample = { text: (

- Icons can also be used within avatars and will be sized - appropriately. + Icons can also be displayed instead of initials or images. When + simply passing an iconType, it will both size and + color appropriately based on the other EuiAvatar{' '} + props. To customize these specifically, pass{' '} + iconSize and iconColor. +

+

+ If your icon is multi- or custom-colored like a logo, you can keep + the default iconColor by passing{' '} + null. Otherwise it will get the appropriate + contrast acceptable variant. Just ensure that you also are providing + an accesible background color to match that of the icon's + color.

), snippet: avatarIconsSnippet, demo: , + props: { EuiAvatar }, }, { title: 'Disabled', @@ -195,6 +202,7 @@ export const AvatarExample = { ), snippet: avatarDisabledSnippet, demo: , + props: { EuiAvatar }, }, ], playground: avatarConfig, diff --git a/src-docs/src/views/avatar/avatar_icon.js b/src-docs/src/views/avatar/avatar_icon.js index f7dcc001d05..9f1eb82cdca 100644 --- a/src-docs/src/views/avatar/avatar_icon.js +++ b/src-docs/src/views/avatar/avatar_icon.js @@ -1,15 +1,46 @@ import React from 'react'; -import { EuiAvatar } from '../../../../src/components'; +import { EuiAvatar, EuiSpacer, EuiTitle } from '../../../../src/components'; export default () => (
- + +

Avatar colors and sizes

+
+ +   - +   - + +   + + + +

Icon colors and sizes

+
+ + +   + +   + +   +   -
); diff --git a/src-docs/src/views/avatar/avatar_type.js b/src-docs/src/views/avatar/avatar_type.js index ebff90d87ef..4f26b625234 100644 --- a/src-docs/src/views/avatar/avatar_type.js +++ b/src-docs/src/views/avatar/avatar_type.js @@ -1,21 +1,19 @@ import React from 'react'; -import { EuiAvatar } from '../../../../src/components'; +import { EuiAvatar, EuiTitle, EuiSpacer } from '../../../../src/components'; export default () => (
- + +

Spaces

+
+ +   - +   - +   - +
); diff --git a/src/components/avatar/__snapshots__/avatar.test.tsx.snap b/src/components/avatar/__snapshots__/avatar.test.tsx.snap index e65d86be680..5a5d3a101ea 100644 --- a/src/components/avatar/__snapshots__/avatar.test.tsx.snap +++ b/src/components/avatar/__snapshots__/avatar.test.tsx.snap @@ -47,6 +47,53 @@ exports[`EuiAvatar props color is rendered 1`] = `
`; +exports[`EuiAvatar props iconType and iconColor as null is rendered 1`] = ` +
+ +
+`; + +exports[`EuiAvatar props iconType and iconColor is rendered 1`] = ` +
+ +
+`; + +exports[`EuiAvatar props iconType and iconSize is rendered 1`] = ` +
+ +
+`; + exports[`EuiAvatar props iconType is rendered 1`] = `
diff --git a/src/components/avatar/avatar.test.tsx b/src/components/avatar/avatar.test.tsx index cebd880dcdf..7e0e3f0dfac 100644 --- a/src/components/avatar/avatar.test.tsx +++ b/src/components/avatar/avatar.test.tsx @@ -53,6 +53,30 @@ describe('EuiAvatar', () => { expect(component).toMatchSnapshot(); }); + + it('and iconSize is rendered', () => { + const component = render( + + ); + + expect(component).toMatchSnapshot(); + }); + + it('and iconColor is rendered', () => { + const component = render( + + ); + + expect(component).toMatchSnapshot(); + }); + + it('and iconColor as null is rendered', () => { + const component = render( + + ); + + expect(component).toMatchSnapshot(); + }); }); describe('size', () => { diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx index 0c421a4c1ba..322371b536f 100644 --- a/src/components/avatar/avatar.tsx +++ b/src/components/avatar/avatar.tsx @@ -23,7 +23,7 @@ import classNames from 'classnames'; import { isColorDark, hexToRgb, isValidHex } from '../../services/color'; import { euiPaletteColorBlindBehindText, toInitials } from '../../services'; -import { IconType, EuiIcon } from '../icon'; +import { IconType, EuiIcon, IconSize, IconColor } from '../icon'; const sizeToClassNameMap = { s: 'euiAvatar--s', @@ -74,6 +74,14 @@ type _EuiAvatarContent = ExclusiveUnion< * Any EUI glyph, logo or custom icon to display instead of initials */ iconType?: IconType; + /** + * Manually change icon color + */ + iconSize?: IconSize; + /** + * Manually change icon size + */ + iconColor?: IconColor | null; } >; @@ -109,6 +117,8 @@ export const EuiAvatar: FunctionComponent = ({ initials, initialsLength, iconType, + iconSize, + iconColor, name, size = 'm', type = 'user', @@ -130,34 +140,40 @@ export const EuiAvatar: FunctionComponent = ({ checkValidColor(color); checkValidInitials(initials); + const assignedColor = + color || visColors[Math.floor(name.length % visColors.length)]; + const textColor = isColorDark(...hexToRgb(assignedColor)) + ? '#FFFFFF' + : '#000000'; + + const avatarStyle = { + backgroundImage: imageUrl ? `url(${imageUrl})` : undefined, + backgroundColor: assignedColor, + color: textColor, + }; + let content; if (!imageUrl && !iconType) { // Create the initials const calculatedInitials = toInitials(name, initialsLength, initials); content = ; } else if (iconType) { + // Allow consumers to let the icons keep their default color (like app icons) + // when passing `iconColor = null`, otherwise continue to pass on `iconColor` or adjust with textColor + const iconCustomColor = + iconColor || iconColor === null ? iconColor : textColor; + content = ( ); } - const assignedColor = - color || visColors[Math.floor(name.length % visColors.length)]; - const textColor = isColorDark(...hexToRgb(assignedColor)) - ? '#FFFFFF' - : '#000000'; - - const avatarStyle = { - backgroundImage: imageUrl ? `url(${imageUrl})` : undefined, - backgroundColor: assignedColor, - color: textColor, - }; - return (
Date: Sat, 6 Mar 2021 13:51:54 -0500 Subject: [PATCH 04/10] Better wordking --- src-docs/src/views/avatar/avatar_example.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src-docs/src/views/avatar/avatar_example.js b/src-docs/src/views/avatar/avatar_example.js index c80c1d45a82..e339160c068 100644 --- a/src-docs/src/views/avatar/avatar_example.js +++ b/src-docs/src/views/avatar/avatar_example.js @@ -166,8 +166,8 @@ export const AvatarExample = { iconSize and iconColor.

- If your icon is multi- or custom-colored like a logo, you can keep - the default iconColor by passing{' '} + If your icon has multiples or custom colors like a logo, you can + keep the default iconColor by passing{' '} null. Otherwise it will get the appropriate contrast acceptable variant. Just ensure that you also are providing an accesible background color to match that of the icon's @@ -194,9 +194,10 @@ export const AvatarExample = { text: (

- While EuiAvatar doesn't accept any interactive behaviors - themselves. You can ensure a visual change if placed within a - disabled element by passing the disabled prop. + While EuiAvatar doesn't accept any interactive + behaviors itself, you can create a visually presented disabled + avatar by adding isDisabled when placed within a + disabled element

), From a7d7b27173b16de0227e4a830dde375b039712d1 Mon Sep 17 00:00:00 2001 From: cchaos Date: Sat, 6 Mar 2021 15:12:48 -0500 Subject: [PATCH 05/10] Fix light/dark mode custom colors --- src-docs/src/views/avatar/avatar_icon.js | 96 +++++++++++++----------- 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/src-docs/src/views/avatar/avatar_icon.js b/src-docs/src/views/avatar/avatar_icon.js index 9f1eb82cdca..eaab684231b 100644 --- a/src-docs/src/views/avatar/avatar_icon.js +++ b/src-docs/src/views/avatar/avatar_icon.js @@ -1,46 +1,56 @@ -import React from 'react'; +import React, { useContext } from 'react'; +import { ThemeContext } from '../../components'; import { EuiAvatar, EuiSpacer, EuiTitle } from '../../../../src/components'; -export default () => ( -
- -

Avatar colors and sizes

-
- - -   - -   - -   - - - -

Icon colors and sizes

-
- - -   - -   - -   - -   -
-); +export default () => { + const themeContext = useContext(ThemeContext); + + /** + * Setup theme based on current light/dark theme + */ + const isDarkTheme = themeContext.theme.includes('dark'); + + return ( +
+ +

Avatar colors and sizes

+
+ + +   + +   + +   + + + +

Icon colors and sizes

+
+ + +   + +   + +   + +   +
+ ); +}; From 4b722bc5af2e9cbc02e4756dfccccb6c8e1d1f63 Mon Sep 17 00:00:00 2001 From: cchaos Date: Sat, 6 Mar 2021 15:35:19 -0500 Subject: [PATCH 06/10] Fixing playground --- src-docs/src/views/avatar/playground.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src-docs/src/views/avatar/playground.js b/src-docs/src/views/avatar/playground.js index 660472dec71..be6e02060c5 100644 --- a/src-docs/src/views/avatar/playground.js +++ b/src-docs/src/views/avatar/playground.js @@ -1,5 +1,9 @@ +import { PropTypes } from 'react-view'; import { EuiAvatar, checkValidColor } from '../../../../src/components/avatar'; -import { propUtilityForPlayground } from '../../services/playground'; +import { + propUtilityForPlayground, + iconValidator, +} from '../../services/playground'; export default () => { const docgenInfo = Array.isArray(EuiAvatar.__docgenInfo) @@ -24,6 +28,13 @@ export default () => { }, }; + propsToUse.initialsLength = { + ...propsToUse.initialsLength, + type: PropTypes.Number, + }; + + propsToUse.iconType = iconValidator(propsToUse.iconType); + return { config: { componentName: 'EuiAvatar', From 7c5a68771654383b692cc980a74bdfae0150cc75 Mon Sep 17 00:00:00 2001 From: cchaos Date: Mon, 8 Mar 2021 14:30:43 -0500 Subject: [PATCH 07/10] Added options for `plain` and `null` colors --- src-docs/src/views/avatar/avatar_example.js | 2 +- src-docs/src/views/avatar/avatar_icon.js | 13 ++-- .../avatar/__snapshots__/avatar.test.tsx.snap | 32 +++++++++- src/components/avatar/_avatar.scss | 4 ++ src/components/avatar/avatar.test.tsx | 14 ++++- src/components/avatar/avatar.tsx | 60 +++++++++++-------- 6 files changed, 91 insertions(+), 34 deletions(-) diff --git a/src-docs/src/views/avatar/avatar_example.js b/src-docs/src/views/avatar/avatar_example.js index e339160c068..aad95da8825 100644 --- a/src-docs/src/views/avatar/avatar_example.js +++ b/src-docs/src/views/avatar/avatar_example.js @@ -197,7 +197,7 @@ export const AvatarExample = { While EuiAvatar doesn't accept any interactive behaviors itself, you can create a visually presented disabled avatar by adding isDisabled when placed within a - disabled element + disabled element.

), diff --git a/src-docs/src/views/avatar/avatar_icon.js b/src-docs/src/views/avatar/avatar_icon.js index eaab684231b..5fefadc1fce 100644 --- a/src-docs/src/views/avatar/avatar_icon.js +++ b/src-docs/src/views/avatar/avatar_icon.js @@ -17,17 +17,18 @@ export default () => {

Avatar colors and sizes

- +   - + +   + -   -

Icon colors and sizes

diff --git a/src/components/avatar/__snapshots__/avatar.test.tsx.snap b/src/components/avatar/__snapshots__/avatar.test.tsx.snap index 5a5d3a101ea..e0e2e0ebfac 100644 --- a/src/components/avatar/__snapshots__/avatar.test.tsx.snap +++ b/src/components/avatar/__snapshots__/avatar.test.tsx.snap @@ -32,7 +32,35 @@ exports[`EuiAvatar is rendered 1`] = `
`; -exports[`EuiAvatar props color is rendered 1`] = ` +exports[`EuiAvatar props color as null is rendered 1`] = ` +
+ +
+`; + +exports[`EuiAvatar props color as plain is rendered 1`] = ` +
+ +
+`; + +exports[`EuiAvatar props color as string is rendered 1`] = `
`; diff --git a/src/components/avatar/_avatar.scss b/src/components/avatar/_avatar.scss index 7ddd413597d..60f5c478a22 100644 --- a/src/components/avatar/_avatar.scss +++ b/src/components/avatar/_avatar.scss @@ -25,6 +25,10 @@ filter: grayscale(100%); } +.euiAvatar--plain { + background-color: $euiColorEmptyShade; +} + // Modifiers for sizing. $avatarSizing: ( s: ( diff --git a/src/components/avatar/avatar.test.tsx b/src/components/avatar/avatar.test.tsx index 7e0e3f0dfac..33dfe144de7 100644 --- a/src/components/avatar/avatar.test.tsx +++ b/src/components/avatar/avatar.test.tsx @@ -114,11 +114,23 @@ describe('EuiAvatar', () => { }); describe('color', () => { - it('is rendered', () => { + it('as string is rendered', () => { const component = render(); expect(component).toMatchSnapshot(); }); + + it('as null is rendered', () => { + const component = render(); + + expect(component).toMatchSnapshot(); + }); + + it('as plain is rendered', () => { + const component = render(); + + expect(component).toMatchSnapshot(); + }); }); describe('isDisabled', () => { diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx index 322371b536f..3a4956e6ea7 100644 --- a/src/components/avatar/avatar.tsx +++ b/src/components/avatar/avatar.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { HTMLAttributes, FunctionComponent } from 'react'; +import React, { HTMLAttributes, FunctionComponent, CSSProperties } from 'react'; import { CommonProps, ExclusiveUnion, keysOf } from '../common'; import classNames from 'classnames'; @@ -64,7 +64,7 @@ type _EuiAvatarContent = ExclusiveUnion< }, { /** - * Path to an image to dispaly instead of initials + * Path to an image to display instead of initials */ imageUrl?: string; } @@ -75,11 +75,11 @@ type _EuiAvatarContent = ExclusiveUnion< */ iconType?: IconType; /** - * Manually change icon color + * Manually change icon size */ iconSize?: IconSize; /** - * Manually change icon size + * Manually change icon color */ iconColor?: IconColor | null; } @@ -94,12 +94,15 @@ export type EuiAvatarProps = Omit, 'color'> & name: string; /** - * Accepts hex value `#FFFFFF`, `#000` otherwise a viz palette color will be assigned + * Accepts hex values like `#FFFFFF`, `#000` otherwise a viz palette color will be assigned. + * Or pass `'plain'` for an empty shade or `null` to remove entirely and the text/icon color will `inherit` */ - color?: string; + color?: string | 'plain' | null; /** - * The type of avatar this is displaying + * The type of avatar mainly controlling the shape. + * `user` = circle + * `space` = rounded square */ type?: EuiAvatarType; size?: EuiAvatarSize; @@ -123,6 +126,7 @@ export const EuiAvatar: FunctionComponent = ({ size = 'm', type = 'user', isDisabled = false, + style, ...rest }) => { const visColors = euiPaletteColorBlindBehindText(); @@ -133,24 +137,37 @@ export const EuiAvatar: FunctionComponent = ({ typeToClassNameMap[type], { 'euiAvatar-isDisabled': isDisabled, + 'euiAvatar--plain': color === 'plain', }, className ); - checkValidColor(color); checkValidInitials(initials); - const assignedColor = - color || visColors[Math.floor(name.length % visColors.length)]; - const textColor = isColorDark(...hexToRgb(assignedColor)) - ? '#FFFFFF' - : '#000000'; + const avatarStyle: CSSProperties = style || {}; + let iconCustomColor = iconColor; - const avatarStyle = { - backgroundImage: imageUrl ? `url(${imageUrl})` : undefined, - backgroundColor: assignedColor, - color: textColor, - }; + const isNamedColor = color === 'plain' || color === null; + if (!isNamedColor) { + checkValidColor(color); + + const assignedColor = + color || visColors[Math.floor(name.length % visColors.length)]; + const textColor = isColorDark(...hexToRgb(assignedColor)) + ? '#FFFFFF' + : '#000000'; + + avatarStyle.backgroundColor = assignedColor; + avatarStyle.color = textColor; + + // Allow consumers to let the icons keep their default color (like app icons) + // when passing `iconColor = null`, otherwise continue to pass on `iconColor` or adjust with textColor + iconCustomColor = iconColor || iconColor === null ? iconColor : textColor; + } + + if (imageUrl) { + avatarStyle.backgroundImage = `url(${imageUrl})`; + } let content; if (!imageUrl && !iconType) { @@ -158,11 +175,6 @@ export const EuiAvatar: FunctionComponent = ({ const calculatedInitials = toInitials(name, initialsLength, initials); content = ; } else if (iconType) { - // Allow consumers to let the icons keep their default color (like app icons) - // when passing `iconColor = null`, otherwise continue to pass on `iconColor` or adjust with textColor - const iconCustomColor = - iconColor || iconColor === null ? iconColor : textColor; - content = ( = ({ // TODO: Migrate to a service export const checkValidColor = (color: EuiAvatarProps['color']) => { - const validHex = color && isValidHex(color); + const validHex = (color && isValidHex(color)) || color === 'plain'; if (color && !validHex) { throw new Error( 'EuiAvatar needs to pass a valid color. This can either be a three ' + From 26c3fcc2f94f14b7b7c15021d1637de1a4343d35 Mon Sep 17 00:00:00 2001 From: cchaos Date: Mon, 8 Mar 2021 14:56:51 -0500 Subject: [PATCH 08/10] cl --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0e9be7745..b35a2cffd35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ - Added `panelProps` to `EuiPopover` ([#4573](https://github.com/elastic/eui/pull/4573)) - Updated the default of the `EuiPopover`s `ownFocus` prop from `false` to `true` ([#4551](https://github.com/elastic/eui/pull/4551)) - Added `src` prop to `EuiImage` as an alternative to `url` ([#4611](https://github.com/elastic/eui/pull/4611)) +- Added `iconType`, `iconColor`, and `iconSize` props to `EuiAvatar` ([#4620](https://github.com/elastic/eui/pull/4620)) +- Added `'plain'` and `null` as `color` options of `EuiAvatar` ([#4620](https://github.com/elastic/eui/pull/4620)) **Bug fixes** From 7e8b7263746da748ab21509e3b3c6df09951ba0e Mon Sep 17 00:00:00 2001 From: cchaos Date: Mon, 8 Mar 2021 16:52:12 -0500 Subject: [PATCH 09/10] Fix heading level --- src-docs/src/views/avatar/avatar_type.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-docs/src/views/avatar/avatar_type.js b/src-docs/src/views/avatar/avatar_type.js index 4f26b625234..c0f76fef9b8 100644 --- a/src-docs/src/views/avatar/avatar_type.js +++ b/src-docs/src/views/avatar/avatar_type.js @@ -5,7 +5,7 @@ import { EuiAvatar, EuiTitle, EuiSpacer } from '../../../../src/components'; export default () => (
-

Spaces

+

Spaces

From f5a8d048aad3eaec03d0529f91f53fc259714620 Mon Sep 17 00:00:00 2001 From: cchaos Date: Wed, 10 Mar 2021 11:24:38 -0500 Subject: [PATCH 10/10] Updating exclusive types` --- src/components/avatar/avatar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx index 3a4956e6ea7..e4dda572ee3 100644 --- a/src/components/avatar/avatar.tsx +++ b/src/components/avatar/avatar.tsx @@ -66,14 +66,14 @@ type _EuiAvatarContent = ExclusiveUnion< /** * Path to an image to display instead of initials */ - imageUrl?: string; + imageUrl: string; } >, { /** * Any EUI glyph, logo or custom icon to display instead of initials */ - iconType?: IconType; + iconType: IconType; /** * Manually change icon size */