Skip to content

Feat(core/avatar)- Added new prop to wrap username when necessary instead of wrapping by default - #2686

Open
1307-Dev wants to merge 3 commits into
mainfrom
feat-ix-2204-avatar
Open

Feat(core/avatar)- Added new prop to wrap username when necessary instead of wrapping by default#2686
1307-Dev wants to merge 3 commits into
mainfrom
feat-ix-2204-avatar

Conversation

@1307-Dev

@1307-Dev 1307-Dev commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

💡 What is the current behavior?

Long usernames passed to ix-avatar via the username prop are always truncated with an ellipsis inside the dropdown of ix-application-header, with no way to display the full text.

GitHub Issue Number: #1583

🆕 What is the new behavior?

Added a new prop- wrapUsername-

  1. (default) — existing behavior: username and extra text are truncated with an ellipsis
  2. username and extra text wrap to multiple lines using overflow-wrap and the dropdown panel height adjusts automatically to show the full content

🏁 Checklist

A pull request can only be merged if all of these conditions are met (where applicable):

  • 🦮 Accessibility (a11y) features were implemented
  • 🗺️ Internationalization (i18n) - no hard coded strings
  • 📲 Responsiveness - components handle viewport changes and content overflow gracefully
  • 📕 Add or update a Storybook story
  • 📄 Documentation was reviewed/updated siemens/ix-docs
  • 🧪 Unit tests were added/updated and pass (pnpm test)
  • 📸 Visual regression tests were added/updated and pass (Guide)
  • 🧐 Static code analysis passes (pnpm lint)
  • 🏗️ Successful compilation (pnpm build, changes pushed)

👨‍💻 Help & support

Summary by CodeRabbit

  • New Features

    • Added an option to wrap long avatar usernames and extra user information instead of truncating them.
    • Avatar menus now expand vertically to display longer usernames while maintaining a fixed popup width.
  • Bug Fixes

    • Improved avatar user information layout to prevent clipping when username wrapping is enabled.
  • Tests

    • Added coverage for enabled and disabled wrapping behavior and long username layouts.

@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for ix-storybook ready!

Name Link
🔨 Latest commit 9c98cc9
🔍 Latest deploy log https://app.netlify.com/projects/ix-storybook/deploys/6a72b915ba357000089aac8b
😎 Deploy Preview https://deploy-preview-2686--ix-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9c98cc9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The avatar component adds an opt-in wrapUsername property. Angular metadata and core typings expose the property. Avatar user information applies wrapping styles when enabled. Regression tests cover class behavior and popup sizing.

Changes

Avatar username wrapping

Layer / File(s) Summary
Public API and option propagation
packages/angular/src/components.ts, packages/core/src/components.d.ts, packages/core/src/components/avatar/avatar.tsx
The wrapUsername property is added to Angular metadata, core typings, and Avatar. The property defaults to false and is passed to dropdown user information.
Wrapping styles and regression coverage
packages/core/src/components/avatar/avatar.scss, packages/core/src/components/avatar/avatar.tsx, packages/core/src/components/avatar/test/avatar.ct.ts
The enabled option applies no-truncation styles for username and extra text. Tests verify conditional class behavior and popup sizing for long usernames.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: danielleroux

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the new avatar prop for controlling username wrapping, which is the main change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-ix-2204-avatar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@1307-Dev 1307-Dev changed the title Feat(core/avatar)- Feat(core/avatar)- Added new prop to wrap username when necessary instead of wrapping by default Aug 4, 2026
@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@1307-Dev
1307-Dev marked this pull request as ready for review August 6, 2026 07:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/components.d.ts`:
- Around line 280-285: Add a changeset for the affected package describing the
new public ix-avatar wrapUsername property and its behavior of wrapping username
and extra text instead of truncating them. Ensure the changeset uses the
appropriate release level; only omit it if you can establish that the change is
internal-only and document that rationale.

In `@packages/core/src/components/avatar/test/avatar.ct.ts`:
- Around line 123-210: Add a hydration assertion immediately after mounting the
Avatar fixture and before interacting with it, verifying the mounted component
is hydrated. In the wrapped dropdown test using wrap-username, run
makeAxeBuilder() against the expanded state and assert there are no
accessibility violations, while preserving the existing class and layout
assertions.
- Around line 167-210: Update the regression test around the avatar popup and
.user-info to validate the visible ix-dropdown panel rather than only the inner
element metrics. Supply a long extra value alongside the long username, then
assert the dropdown expands or that the complete username and extra content
remain visible after the update.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c971f80f-fb16-465d-afdf-7c8a24788a50

📥 Commits

Reviewing files that changed from the base of the PR and between 60d38b5 and 9c98cc9.

⛔ Files ignored due to path filters (3)
  • packages/angular/standalone/src/components.ts is excluded by !packages/angular/standalone/src/components.ts
  • packages/react/src/components/components.server.ts is excluded by !packages/react/src/components/**
  • packages/vue/src/components/ix-avatar.ts is excluded by !packages/vue/src/components/**
📒 Files selected for processing (5)
  • packages/angular/src/components.ts
  • packages/core/src/components.d.ts
  • packages/core/src/components/avatar/avatar.scss
  • packages/core/src/components/avatar/avatar.tsx
  • packages/core/src/components/avatar/test/avatar.ct.ts

Comment on lines +280 to +285
/**
* If `true`, the username and extra text will wrap to multiple lines instead of being truncated with an ellipsis. Note: Only working if avatar is part of the ix-application-header
* @since 5.2.0
* @default false
*/
"wrapUsername": boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add a changeset for this public API change.

wrapUsername adds a public ix-avatar property and changes username and extra-text rendering. Add a changeset for the affected package with the consumer-facing behavior. If no changeset is intended, state why the change is internal-only.

As per path instructions, “Changesets are required for public API updates and behavior changes.”

Also applies to: 7052-7057, 12014-12014

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components.d.ts` around lines 280 - 285, Add a changeset
for the affected package describing the new public ix-avatar wrapUsername
property and its behavior of wrapping username and extra text instead of
truncating them. Ensure the changeset uses the appropriate release level; only
omit it if you can establish that the change is internal-only and document that
rationale.

Source: Path instructions

Comment on lines +123 to +210
regressionTest(
'should apply no-truncate class when wrapUsername is true',
async ({ page, mount }) => {
await page.setViewportSize(viewPorts.lg);
await mount(
`
<ix-application-header name="Test">
<ix-avatar username="foo" wrap-username>
</ix-avatar>
</ix-application-header>
`
);

const avatar = page.locator('ix-avatar');
await avatar.click();

await expect(avatar.locator('.user-info')).toHaveClass(
/\buser-info--no-truncate\b/
);
}
);

regressionTest(
'should not apply no-truncate class when wrapUsername is false',
async ({ page, mount }) => {
await page.setViewportSize(viewPorts.lg);
await mount(
`
<ix-application-header name="Test">
<ix-avatar username="foo">
</ix-avatar>
</ix-application-header>
`
);

const avatar = page.locator('ix-avatar');
await avatar.click();

await expect(avatar.locator('.user-info')).not.toHaveClass(
/\buser-info--no-truncate\b/
);
}
);

regressionTest(
'should keep the popup width fixed and wrap long usernames when wrapUsername is true',
async ({ page, mount }) => {
await page.setViewportSize(viewPorts.lg);
await mount(
`
<ix-application-header name="Test">
<ix-avatar username="foo" wrap-username>
</ix-avatar>
</ix-application-header>
`
);

const avatar = page.locator('ix-avatar');
await avatar.click();

const userInfo = avatar.locator('.user-info');

const initialMetrics = await userInfo.evaluate((element) => {
const rect = element.getBoundingClientRect();
return {
width: Math.round(rect.width),
height: Math.round(rect.height),
};
});

const longUsername = 'verylongstringthatisnotfullydisplayed';
await avatar.evaluate((element, value) => {
element.setAttribute('username', value);
}, longUsername);

await expect(userInfo).toHaveText(new RegExp(longUsername));

const updatedMetrics = await userInfo.evaluate((element) => {
const rect = element.getBoundingClientRect();
return {
width: Math.round(rect.width),
height: Math.round(rect.height),
};
});

expect(updatedMetrics.width).toBe(initialMetrics.width);
expect(updatedMetrics.height).toBeGreaterThan(initialMetrics.height);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add the required accessibility and hydration coverage.

Add a makeAxeBuilder() assertion for the wrapped dropdown state. Add a basic assertion that the mounted Avatar is hydrated before interaction.

As per coding guidelines, “Include accessibility coverage using makeAxeBuilder and a basic hydration/render test in component test files.” As per path instructions, “Ensure tests include both: accessibility test using makeAxeBuilder() and renders test verifying hydration.”

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 197-197: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(longUsername)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 197-197: Do not use variable for regular expressions
Context: new RegExp(longUsername)
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal-typescript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/avatar/test/avatar.ct.ts` around lines 123 -
210, Add a hydration assertion immediately after mounting the Avatar fixture and
before interacting with it, verifying the mounted component is hydrated. In the
wrapped dropdown test using wrap-username, run makeAxeBuilder() against the
expanded state and assert there are no accessibility violations, while
preserving the existing class and layout assertions.

Sources: Coding guidelines, Path instructions

Comment on lines +167 to +210
regressionTest(
'should keep the popup width fixed and wrap long usernames when wrapUsername is true',
async ({ page, mount }) => {
await page.setViewportSize(viewPorts.lg);
await mount(
`
<ix-application-header name="Test">
<ix-avatar username="foo" wrap-username>
</ix-avatar>
</ix-application-header>
`
);

const avatar = page.locator('ix-avatar');
await avatar.click();

const userInfo = avatar.locator('.user-info');

const initialMetrics = await userInfo.evaluate((element) => {
const rect = element.getBoundingClientRect();
return {
width: Math.round(rect.width),
height: Math.round(rect.height),
};
});

const longUsername = 'verylongstringthatisnotfullydisplayed';
await avatar.evaluate((element, value) => {
element.setAttribute('username', value);
}, longUsername);

await expect(userInfo).toHaveText(new RegExp(longUsername));

const updatedMetrics = await userInfo.evaluate((element) => {
const rect = element.getBoundingClientRect();
return {
width: Math.round(rect.width),
height: Math.round(rect.height),
};
});

expect(updatedMetrics.width).toBe(initialMetrics.width);
expect(updatedMetrics.height).toBeGreaterThan(initialMetrics.height);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Test the visible dropdown result.

The test measures only .user-info. It can pass if ix-dropdown clips the expanded content. Assert that the dropdown panel expands or that the complete long content remains visible. Include a long extra value because wrapUsername changes both user-information fields.

As per coding guidelines, “Update tests ... when user-facing behavior ... changes.”

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 197-197: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(longUsername)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 197-197: Do not use variable for regular expressions
Context: new RegExp(longUsername)
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal-typescript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/avatar/test/avatar.ct.ts` around lines 167 -
210, Update the regression test around the avatar popup and .user-info to
validate the visible ix-dropdown panel rather than only the inner element
metrics. Supply a long extra value alongside the long username, then assert the
dropdown expands or that the complete username and extra content remain visible
after the update.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant