tegel icon indicating copy to clipboard operation
tegel copied to clipboard

[Bug report]: TdsHeaderItem ignores slot="end" when *ngIf directive value changes

Open Patrick2607 opened this issue 1 year ago • 0 comments

Requirements before reporting

  • [X] No duplicated issue reported.
  • [X] I have checked the latest version if the bug exist there. See all available packages at npmJS.com
  • [X] I have followed the installation guide.

Package versions

@scania/tegel-angular: 1.6.1

Browser

Firefox

Framework

Angular

Version

Angular 16.2.0

Reproduction steps

  1. Write a TdsHeader and one or more TdsHeaderItem elements in your html template
  2. Set an *ngIf directive on the TdsHeaderItem together with slot="end"
  3. Change the value *ngIf directive

Code example

HTML template:

<tds-header *ngIf="vm$ | async as vm">
  <!-- Other items -->
  <tds-header-item slot="end" *ngIf="vm.user" title="Orders">
    <a routerLink="/orders">Orders</a>
  </tds-header-item>
  <!-- Other items -->
</tds-header>

TS component:

export class NavbarComponent {  
  private readonly document: Document = inject(DOCUMENT);

  // KeyPress event to toggle the ngIf directive
  private readonly user$ = fromEvent<KeyboardEvent>(
    this.document,
    'keydown'
  ).pipe(
    filter((e: KeyboardEvent) => e.key === 'x'),
    startWith(undefined),
    scan((acc: boolean) => !acc, false)
  );

  // View model for the html template
  readonly vm$ = combineLatest({
    user: this.user$,
    // Other exposed variables
  }).pipe(
    //concatMap((value) => of(null, value).pipe(delay(0)))
  );
}

Please note that I’ve constructed a basic example to illustrate this issue. You can replicate the behavior by copying and pasting the provided code into your environment. Once you’ve done that, press X in your browser to toggle the value of the *ngIf directive. Initially, you’ll observe that it renders on the right side. However, upon disabling and re-enabling it, the rendering shifts to the left instead of maintaining its position on the right.

I’ve implemented a temporary workaround for this issue by triggering a ‘re-render’ of the entire TdsHeader component whenever the view model vm$ emits. However, this is merely a quick fix as it causes all child components to re-render as well. To illustrate this, please uncomment the concatMap function operator in the pipe. Here’s what happens: when vm$ emits, it first emits a null value. This effectively unrenders the entire TdsHeader component due to its *ngIf directive: <tds-header *ngIf="vm$ | async as vm">. Following this, it emits the actual value, which triggers a re-render of the entire TdsHeader component. As a result, the TdsHeaderItems are correctly positioned.

Screenshots

tdsheader_bugreport

Expected behaviour

The TdsHeaderItem element should consistently stay anchored to the right side, regardless of whether the element has been re-rendered or not.

Console errors

No response

Contact information

[email protected]

Patrick2607 avatar Feb 23 '24 09:02 Patrick2607