diff --git a/.changeset/slick-worms-drum.md b/.changeset/slick-worms-drum.md new file mode 100644 index 0000000000..4fb170655b --- /dev/null +++ b/.changeset/slick-worms-drum.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fixes for rendering initials in the avatar component. diff --git a/packages/core-components/src/components/Avatar/util.test.ts b/packages/core-components/src/components/Avatar/util.test.ts index 98d0bd2550..123526973b 100644 --- a/packages/core-components/src/components/Avatar/util.test.ts +++ b/packages/core-components/src/components/Avatar/util.test.ts @@ -42,4 +42,24 @@ describe('extractInitials', () => { it('removes spaces from beginning or the end', () => { expect(extractInitials(' John Jonathan Doe ')).toEqual('JD'); }); + + it('handles any sequence of whitespace between words', () => { + expect(extractInitials('John\tJonathan Doe')).toEqual('JD'); + expect(extractInitials(' John\nDoe ')).toEqual('JD'); + expect(extractInitials('John\r\nDoe')).toEqual('JD'); + }); + + it('removes bracketed content from initials', () => { + expect(extractInitials('John Doe (jd1234)')).toEqual('JD'); + expect(extractInitials('Jane Smith [js5678]')).toEqual('JS'); + expect(extractInitials('Alice (admin) Johnson')).toEqual('AJ'); + expect(extractInitials('(admin) Alice Johnson')).toEqual('AJ'); + }); + + it('removes non-letter characters from initials', () => { + expect(extractInitials('John D0e!')).toEqual('JD'); + expect(extractInitials("Ann-Marie O'Neil")).toEqual('AO'); + expect(extractInitials('Élodie Brûlé!')).toEqual('ÉB'); + expect(extractInitials('Doe1231*')).toEqual('D'); + }); }); diff --git a/packages/core-components/src/components/Avatar/utils.ts b/packages/core-components/src/components/Avatar/utils.ts index 65e2be6afa..01fde6ffc0 100644 --- a/packages/core-components/src/components/Avatar/utils.ts +++ b/packages/core-components/src/components/Avatar/utils.ts @@ -28,7 +28,13 @@ export function stringToColor(str: string) { } export function extractInitials(name: string) { - const names = name.trim().split(' '); + const names = name + .replace(/\([^)]{0,1000}\)/g, '') + .replace(/\[[^\]]{0,1000}\]/g, '') + .trim() + .split(/\s+/) + .map(word => word.replace(/[^A-Za-z\u00C0-\u017F]/g, '')) + .filter(Boolean); const firstName = names[0] ?? ''; const lastName = names.length > 1 ? names[names.length - 1] : ''; return firstName && lastName