Why is my expand/collapse animation "jumping"?

Discussão em 'Angular' iniciado por Razzer, Dezembro 23, 2024.

  1. Razzer

    Razzer Guest

    I am working on an Angular 17 project with a Tailwind CSS-styled sidebar.

    The expand/collapse functionality works as intended, but the animation is not as smooth as I would like. There is a noticeable "jump" in the animation, which disrupts the smooth transition I aim for. Ideally, the animation should smoothly transition from the top to bottom (and vice versa) without glitches.

    Showcase of the problem: https://i.imgur.com/4RpEwYv.gif

    My HTML Code:

    <div class="flex h-screen bg-white">
    <aside class="w-72 bg-gray-900 shadow-lg flex flex-col">
    <!-- Navigation -->
    <nav class="p-4 pl-0 overflow-y-auto">
    @for (group of navigation; track $index) {
    <div class="mb-2" [class.pb-3]="$index != navigation.length - 1">
    <div class="flex flex-col">
    <div class="flex items-center justify-between pl-2 pr-0 cursor-pointer gap-2 w-[104%]" (click)="toggleGroup(group.category)">
    <div>
    <h3 class="px-0 mb-0 text-xs font-semibold text-gray-500 uppercase tracking-wider text-{{group.color}}-gradient">
    {{ group.category }}
    </h3>
    <p class="text-xs text-gray-500 mb-0">{{ group.description }}</p>
    </div>
    </div>
    </div>

    <div class="mt-2 space-y-1 overflow-hidden" [@expandCollapse]="expandedGroups[group.category] ? 'expanded' : 'collapsed'">
    <div class="space-y-1">

    <!-- Show only 3 pages if group is not expanded & be able to expand it -->
    @for (page of (expandedGroups[group.category] ? group.pages : group.pages.slice(0, 3)); track $index) {
    <a [routerLink]="page.redirect_url"
    class="flex items-center p-2 !text-slate-400 hover:bg-gray-500 rounded-lg transition-none hover:!text-white">
    <div class="w-6 flex-shrink-0">
    <fa-icon [icon]="page.icon"></fa-icon>
    </div>
    <span class="ml-3 text-[0.9rem]">{{ page.title }}</span>
    </a>
    }
    </div>
    </div>
    </div>
    }
    </nav>

    </aside>
    </div>


    TypeScript Code with Angular animation part:

    @Component({
    selector: 'app-dashboard',
    standalone: true,
    imports: [
    NgOptimizedImage,
    RouterLink,
    FaIconComponent,
    ],
    templateUrl: './dashboard.component.html',
    styleUrl: './dashboard.component.scss',
    animations: [
    trigger('expandCollapse', [
    state('collapsed', style({
    height: '86px',
    overflow: 'hidden',
    opacity: 1
    })),
    state('expanded', style({
    height: '*',
    overflow: 'hidden',
    opacity: 1
    })),
    transition('expanded => collapsed', [
    style({ height: '*' }),
    animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)',
    style({ height: '96px' })
    )
    ]),
    transition('collapsed => expanded', [
    style({ height: '96px' }),
    animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)',
    style({ height: '*' })
    )
    ])
    ])
    ]
    })
    export class DashboardComponent {
    // it is filled, but commented out
    navigation = []

    expandedGroups: { [key: string]: boolean } = {};

    toggleGroup(category: string) {
    this.expandedGroups[category] = !this.expandedGroups[category];
    }

    constructor() {
    this.navigation.forEach(group => {
    this.expandedGroups[group.category] = false;
    });
    }

    Continue reading...

Compartilhe esta Página