From 6e56f07ff3a33ac45c0e15180c6a48675c345a0b Mon Sep 17 00:00:00 2001 From: Katie McFaul Date: Fri, 12 Jun 2026 10:48:47 -0400 Subject: [PATCH 1/4] feat(Avatar): support colorful --- packages/react-core/package.json | 2 +- .../src/components/Avatar/Avatar.tsx | 42 +++++++++++---- .../Avatar/__tests__/Avatar.test.tsx | 29 +++++++++++ .../src/components/Avatar/examples/Avatar.md | 29 ++++++++++- .../Avatar/examples/AvatarBasic.tsx | 2 +- .../Avatar/examples/AvatarBordered.tsx | 2 +- .../Avatar/examples/AvatarColorful.tsx | 42 +++++++++++++++ .../Avatar/examples/AvatarIcons.tsx | 51 +++++++++++++++++++ .../Avatar/examples/AvatarInitials.tsx | 14 +++++ .../Avatar/examples/AvatarSizeVariations.tsx | 13 +---- .../src/components/Avatar/examples/avatar.css | 6 +++ .../components/assets/img_avatar-light.svg | 25 +++++++++ packages/react-docs/package.json | 2 +- packages/react-icons/package.json | 2 +- packages/react-styles/package.json | 2 +- packages/react-tokens/package.json | 2 +- yarn.lock | 18 +++---- 17 files changed, 244 insertions(+), 39 deletions(-) create mode 100644 packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx create mode 100644 packages/react-core/src/components/Avatar/examples/AvatarIcons.tsx create mode 100644 packages/react-core/src/components/Avatar/examples/AvatarInitials.tsx create mode 100644 packages/react-core/src/components/Avatar/examples/avatar.css create mode 100644 packages/react-core/src/components/assets/img_avatar-light.svg diff --git a/packages/react-core/package.json b/packages/react-core/package.json index 8a757016ea9..4c4ef3fb4ef 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -54,7 +54,7 @@ "tslib": "^2.8.1" }, "devDependencies": { - "@patternfly/patternfly": "6.5.2", + "@patternfly/patternfly": "6.6.0-prerelease.8", "case-anything": "^3.1.2", "css": "^3.0.0", "fs-extra": "^11.3.3" diff --git a/packages/react-core/src/components/Avatar/Avatar.tsx b/packages/react-core/src/components/Avatar/Avatar.tsx index 1f1c2f2cde5..a13105e9ae5 100644 --- a/packages/react-core/src/components/Avatar/Avatar.tsx +++ b/packages/react-core/src/components/Avatar/Avatar.tsx @@ -5,31 +5,55 @@ export interface AvatarProps extends React.DetailedHTMLProps< React.ImgHTMLAttributes, HTMLImageElement > { + /** Content rendered inside the avatar. */ + children?: React.ReactNode; /** Additional classes added to the avatar. */ className?: string; /** Attribute that specifies the URL of the image for the avatar. */ src?: string; - /** Attribute that specifies the alternate text of the image for the avatar. */ + /** Attribute that specifies the alternate text of the image for the avatar. Will set aria-label for children or initials avatars. */ alt: string; /** Flag to indicate the avatar should have a border. */ isBordered?: boolean; /** Size variant of avatar. */ size?: 'sm' | 'md' | 'lg' | 'xl'; + /** Color of the avatar. */ + color?: 'red' | 'orangered' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'purple' | 'gray'; + /** Initials of the avatar. */ + initials?: string; } export const Avatar: React.FunctionComponent = ({ + children, className, src = '', alt, isBordered, size, + color, + initials, ...props -}: AvatarProps) => ( - {alt} -); +}: AvatarProps) => { + const avatarClasses = css(styles.avatar, styles.modifiers[size], isBordered && styles.modifiers.bordered, className); + + if (initials || children) { + return ( +
+ {initials && ( + + )} + {children && children} +
+ ); + } + + return {alt}; +}; Avatar.displayName = 'Avatar'; diff --git a/packages/react-core/src/components/Avatar/__tests__/Avatar.test.tsx b/packages/react-core/src/components/Avatar/__tests__/Avatar.test.tsx index 8f3b066e074..1b509a48155 100644 --- a/packages/react-core/src/components/Avatar/__tests__/Avatar.test.tsx +++ b/packages/react-core/src/components/Avatar/__tests__/Avatar.test.tsx @@ -62,6 +62,35 @@ test('Renders with passed aria-label prop', () => { expect(screen.getByRole('img')).toHaveAccessibleName('Avatar test'); }); +test('Renders with passed initials prop', () => { + render(); + expect(screen.getByText('AB')).toBeVisible(); +}); + +test('Renders with passed children prop', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test(`Renders with class name ${styles.modifiers.colorful} when color prop is passed`, () => { + render( + + Test + + ); + expect(screen.getByText('Test')).toHaveClass(styles.modifiers.colorful); +}); + +const colors = ['red', 'orangered', 'orange', 'yellow', 'green', 'teal', 'blue', 'purple', 'gray'] as const; +test.each(colors)('Renders with passed color prop: %s', (color) => { + render( + + Test + + ); + expect(screen.getByText('Test')).toHaveClass(styles.modifiers[color]); +}); + test('Matches the snapshot', () => { const { asFragment } = render(); diff --git a/packages/react-core/src/components/Avatar/examples/Avatar.md b/packages/react-core/src/components/Avatar/examples/Avatar.md index 75417fde012..5280a7ef360 100644 --- a/packages/react-core/src/components/Avatar/examples/Avatar.md +++ b/packages/react-core/src/components/Avatar/examples/Avatar.md @@ -5,22 +5,47 @@ cssPrefix: pf-v6-c-avatar propComponents: ['Avatar'] --- +import './avatar.css'; import { Fragment } from 'react'; -import avatarImg from '../../assets/avatarImg.svg'; +import avatarImg from '../../assets/img_avatar-light.svg'; +import RhUiAiChatbotIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ai-chatbot-icon'; ## Examples ### Basic ```ts file="./AvatarBasic.tsx" + ``` -### Bordered +### Bordered ```ts file="./AvatarBordered.tsx" + ``` ### Size variations ```ts file="./AvatarSizeVariations.tsx" + +``` + +## Colorful avatars + +### With svgs + +```ts file="./AvatarColorful.tsx" + +``` + +### With initials + +```ts file="./AvatarInitials.tsx" + +``` + +### With icons + +```ts file="./AvatarIcons.tsx" + ``` diff --git a/packages/react-core/src/components/Avatar/examples/AvatarBasic.tsx b/packages/react-core/src/components/Avatar/examples/AvatarBasic.tsx index a166aceb2c3..d7dc488302a 100644 --- a/packages/react-core/src/components/Avatar/examples/AvatarBasic.tsx +++ b/packages/react-core/src/components/Avatar/examples/AvatarBasic.tsx @@ -1,4 +1,4 @@ import { Avatar } from '@patternfly/react-core'; -import avatarImg from '../../assets/avatarImg.svg'; +import avatarImg from '../../assets/img_avatar-light.svg'; ; diff --git a/packages/react-core/src/components/Avatar/examples/AvatarBordered.tsx b/packages/react-core/src/components/Avatar/examples/AvatarBordered.tsx index 429589810e2..a8e90c5a6dc 100644 --- a/packages/react-core/src/components/Avatar/examples/AvatarBordered.tsx +++ b/packages/react-core/src/components/Avatar/examples/AvatarBordered.tsx @@ -1,4 +1,4 @@ import { Avatar } from '@patternfly/react-core'; -import avatarImg from '../../assets/avatarImg.svg'; +import avatarImg from '../../assets/img_avatar-light.svg'; ; diff --git a/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx b/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx new file mode 100644 index 00000000000..d9213af7971 --- /dev/null +++ b/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx @@ -0,0 +1,42 @@ +import { Fragment } from 'react'; +import { Avatar } from '@patternfly/react-core'; + +const _avatarIcon = ( + +); + + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + + + {_avatarIcon} + +; diff --git a/packages/react-core/src/components/Avatar/examples/AvatarIcons.tsx b/packages/react-core/src/components/Avatar/examples/AvatarIcons.tsx new file mode 100644 index 00000000000..4e8ec98d599 --- /dev/null +++ b/packages/react-core/src/components/Avatar/examples/AvatarIcons.tsx @@ -0,0 +1,51 @@ +import { Fragment } from 'react'; +import { Avatar, Icon } from '@patternfly/react-core'; +import RhUiAiChatbotIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ai-chatbot-icon'; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; diff --git a/packages/react-core/src/components/Avatar/examples/AvatarInitials.tsx b/packages/react-core/src/components/Avatar/examples/AvatarInitials.tsx new file mode 100644 index 00000000000..4ffd51b7291 --- /dev/null +++ b/packages/react-core/src/components/Avatar/examples/AvatarInitials.tsx @@ -0,0 +1,14 @@ +import { Fragment } from 'react'; +import { Avatar } from '@patternfly/react-core'; + + + + + + + + + + + +; diff --git a/packages/react-core/src/components/Avatar/examples/AvatarSizeVariations.tsx b/packages/react-core/src/components/Avatar/examples/AvatarSizeVariations.tsx index 05ae1781ecd..d00d8354c05 100644 --- a/packages/react-core/src/components/Avatar/examples/AvatarSizeVariations.tsx +++ b/packages/react-core/src/components/Avatar/examples/AvatarSizeVariations.tsx @@ -1,21 +1,10 @@ import { Fragment } from 'react'; import { Avatar } from '@patternfly/react-core'; -import avatarImg from '../../assets/avatarImg.svg'; +import avatarImg from '../../assets/img_avatar-light.svg'; - Small -
-
- Medium -
-
- Large -
-
- Extra Large -
; diff --git a/packages/react-core/src/components/Avatar/examples/avatar.css b/packages/react-core/src/components/Avatar/examples/avatar.css new file mode 100644 index 00000000000..97c8fe16ee0 --- /dev/null +++ b/packages/react-core/src/components/Avatar/examples/avatar.css @@ -0,0 +1,6 @@ +#ws-react-c-avatar-with-svgs, +#ws-react-c-avatar-with-initials, +#ws-react-c-avatar-with-icons { + display: flex; + gap: 3px; +} diff --git a/packages/react-core/src/components/assets/img_avatar-light.svg b/packages/react-core/src/components/assets/img_avatar-light.svg new file mode 100644 index 00000000000..dd04ff0cddf --- /dev/null +++ b/packages/react-core/src/components/assets/img_avatar-light.svg @@ -0,0 +1,25 @@ + + + + + + + + + \ No newline at end of file diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index f4cee2234e7..4a4662c464e 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -23,7 +23,7 @@ "test:a11y": "patternfly-a11y --config patternfly-a11y.config" }, "dependencies": { - "@patternfly/patternfly": "6.5.2", + "@patternfly/patternfly": "6.6.0-prerelease.8", "@patternfly/react-charts": "workspace:^", "@patternfly/react-code-editor": "workspace:^", "@patternfly/react-core": "workspace:^", diff --git a/packages/react-icons/package.json b/packages/react-icons/package.json index da2936519f3..571a8aee467 100644 --- a/packages/react-icons/package.json +++ b/packages/react-icons/package.json @@ -35,7 +35,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", - "@patternfly/patternfly": "6.5.2", + "@patternfly/patternfly": "6.6.0-prerelease.8", "@rhds/icons": "^2.2.0", "fs-extra": "^11.3.3", "tslib": "^2.8.1" diff --git a/packages/react-styles/package.json b/packages/react-styles/package.json index f570cf5a684..eda179c67fd 100644 --- a/packages/react-styles/package.json +++ b/packages/react-styles/package.json @@ -19,7 +19,7 @@ "clean": "rimraf dist css" }, "devDependencies": { - "@patternfly/patternfly": "6.5.2", + "@patternfly/patternfly": "6.6.0-prerelease.8", "change-case": "^5.4.4", "fs-extra": "^11.3.3" }, diff --git a/packages/react-tokens/package.json b/packages/react-tokens/package.json index 1ccbf347a98..8df9685f791 100644 --- a/packages/react-tokens/package.json +++ b/packages/react-tokens/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@adobe/css-tools": "^4.4.4", - "@patternfly/patternfly": "6.5.2", + "@patternfly/patternfly": "6.6.0-prerelease.8", "fs-extra": "^11.3.3" } } diff --git a/yarn.lock b/yarn.lock index 402beec4953..8e8f493a823 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5070,10 +5070,10 @@ __metadata: languageName: node linkType: hard -"@patternfly/patternfly@npm:6.5.2": - version: 6.5.2 - resolution: "@patternfly/patternfly@npm:6.5.2" - checksum: 10c0/39a6d06f831f1783b6003dfc98c028c653485e2cd6d15fbad3199514161e249fdff8519e29145a082a174a1b4cbdd21d1f716ddcd1d5c00abfeaacabca0b2518 +"@patternfly/patternfly@npm:6.6.0-prerelease.8": + version: 6.6.0-prerelease.8 + resolution: "@patternfly/patternfly@npm:6.6.0-prerelease.8" + checksum: 10c0/4b701fa77965049934d570f3ea4003326fe213ce38c5c129f83c9cbc2652f8788feccb92eaa1be3e99f5f5ed7c836368b454ad5fd0135cfff4833fffada0203f languageName: node linkType: hard @@ -5171,7 +5171,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-core@workspace:packages/react-core" dependencies: - "@patternfly/patternfly": "npm:6.5.2" + "@patternfly/patternfly": "npm:6.6.0-prerelease.8" "@patternfly/react-icons": "workspace:^" "@patternfly/react-styles": "workspace:^" "@patternfly/react-tokens": "workspace:^" @@ -5192,7 +5192,7 @@ __metadata: resolution: "@patternfly/react-docs@workspace:packages/react-docs" dependencies: "@patternfly/documentation-framework": "npm:^6.36.8" - "@patternfly/patternfly": "npm:6.5.2" + "@patternfly/patternfly": "npm:6.6.0-prerelease.8" "@patternfly/patternfly-a11y": "npm:5.1.0" "@patternfly/react-charts": "workspace:^" "@patternfly/react-code-editor": "workspace:^" @@ -5232,7 +5232,7 @@ __metadata: "@fortawesome/free-brands-svg-icons": "npm:^5.15.4" "@fortawesome/free-regular-svg-icons": "npm:^5.15.4" "@fortawesome/free-solid-svg-icons": "npm:^5.15.4" - "@patternfly/patternfly": "npm:6.5.2" + "@patternfly/patternfly": "npm:6.6.0-prerelease.8" "@rhds/icons": "npm:^2.2.0" fs-extra: "npm:^11.3.3" tslib: "npm:^2.8.1" @@ -5319,7 +5319,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-styles@workspace:packages/react-styles" dependencies: - "@patternfly/patternfly": "npm:6.5.2" + "@patternfly/patternfly": "npm:6.6.0-prerelease.8" change-case: "npm:^5.4.4" fs-extra: "npm:^11.3.3" languageName: unknown @@ -5361,7 +5361,7 @@ __metadata: resolution: "@patternfly/react-tokens@workspace:packages/react-tokens" dependencies: "@adobe/css-tools": "npm:^4.4.4" - "@patternfly/patternfly": "npm:6.5.2" + "@patternfly/patternfly": "npm:6.6.0-prerelease.8" fs-extra: "npm:^11.3.3" languageName: unknown linkType: soft From a04850400694feff4d07cebc6fc5860e4027b3b6 Mon Sep 17 00:00:00 2001 From: Katie McFaul Date: Fri, 12 Jun 2026 10:56:22 -0400 Subject: [PATCH 2/4] update example syntax --- .../Avatar/examples/AvatarColorful.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx b/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx index d9213af7971..010e733cd33 100644 --- a/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx +++ b/packages/react-core/src/components/Avatar/examples/AvatarColorful.tsx @@ -1,7 +1,7 @@ import { Fragment } from 'react'; import { Avatar } from '@patternfly/react-core'; -const _avatarIcon = ( +const avatarSvg = (