GovAlta / ui-components

ui-components contains the code you need to start building a user interface for Government of Alberta platforms and services.
Apache License 2.0
14 stars 23 forks source link

App Header: doesn't work with Angular ng-container *ngIf #1563

Closed mtycholaz closed 3 days ago

mtycholaz commented 6 months ago

Describe the bug

We created a component that uses the goa-app-header component. We're using the Angular <ng-content></ng-content> element so that we can use our component in multiple areas of the app. We've noticed that the menu breaks when in mobile view. Adding a dummy element appears to fix the issue.

@abgov/angular-components ^2.5.0 @abgov/web-components ^1.18.0

Provide Code

@Component({
    selector: 'shared-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.scss']
})
export class HeaderComponent {}

<goa-app-header heading="Prepare family court documents">
    <ng-content></ng-content>->
</goa-app-header>
<shared-header>
    <!-- This is the important part. Also the variable needs to be filled in async, not static -->
    <ng-container *ngIf="currentProfile; then loggedInUser; else notLoggedIn"></ng-container>
</shared-header>

<ng-template #loggedInUser>
User is logged in
</ng-template>

<ng-template #notLoggedIn>
User is not logged in
</ng-template>

To Reproduce

  1. Create an angular component with the above code
  2. Then use the shared-header component (see above code)
  3. Open your browser devtools and enable device emulation. Pick a mobile profile.
  4. Refresh the page and the mobile menu button will be missing.
  5. If you expand the size to desktop and then back, the mobile menu appears, but there's now a console error.

image

Relevant console log output

ERROR TypeError: Cannot read properties of undefined (reading 'appendChild')
    at Ut (web-components.umd.js:5:7037)
    at web-components.umd.js:148:10773
    at yt (web-components.umd.js:2:404)
    at Array.map (<anonymous>)
    at $a.connectedCallback (web-components.umd.js:5:5950)
    at _ZoneDelegate.invoke (zone.js:372:26)
    at Object.onInvoke (core.mjs:24313:33)
    at _ZoneDelegate.invoke (zone.js:371:52)
    at Zone.runGuarded (zone.js:144:47)
    at $a.connectedCallback (zone.js:128:29)

What browsers are you seeing the problem on?

Firefox, Chrome, Safari, Edge, Mobile Android, Mobile iOS

Additional info

From Dustin: This is likely an issue with this code specifically in our AppHeader.svelte:

// *Menu* children count
  // When in mobile mode, while the children are not visible the children are rendered in a div[display: none]
  // element to allow for the children count to be obtained.
  async function hasChildren() {
    await tick();

    if (!_slotParentEl) return;

    const slot = (_slotParentEl?.childNodes[0] as HTMLSlotElement);
    const children = slot.assignedElements?.();
    if (children) {
      return children.length > 0;
    } else {
      // testing
      return [..._slotParentEl.querySelectorAll("a")].length > 0
    }
  }

Because the div in mobile mode is being rendered with a display:none around it. Likely because getting the variable back that's being checked in the ngIf is taking longer.

Update 2024-01-22

Source of the problem appears to be the *ngIf on the <ng-container> element within the header

ArakTaiRoth commented 5 months ago

@ArakTaiRoth Look into after the Svelte4 Upgrade is pushed to see if it's still an issue

ArakTaiRoth commented 4 months ago

Don't pick this up. I've tested and can't replicate anymore with the new Svelte upgrade. I've spoken to @mtycholaz about this and he'll be testing as well himself to confirm.

chrisolsen commented 1 week ago

I am also unable to replicate this when using the current alpha branch

ArakTaiRoth commented 3 days ago

Closing, as that's 2 people that are no longer able to replicate.