Skip to content

Commit

Permalink
fix(ɵtoolkit/accordion): remove viewport from accordion
Browse files Browse the repository at this point in the history
It turned out to be impractical to put the accordion in a viewport by default. Instead, it should be left to the developer to decide. Perhaps, if at all, only certain accordion item need to be displayed in a viewport.
  • Loading branch information
danielwiehl authored and mofogasy committed Jan 15, 2021
1 parent 8033a79 commit ff0aac3
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
<sci-viewport>
<div cdkAccordion [multi]="multi" sciDimension #accordion_size="sciDimension">
<div sciDimension #accordion_client_size="sciDimension"
class="accordion-client"
[class.filled]="accordion_size.dimension.offsetHeight === accordion_client_size.dimension.offsetHeight">
<section #section
*ngFor="let item of items; trackBy: trackByFn"
class="accordion-item e2e-accordion-item"
[class.e2e-expanded]="cdkAccordionItem.expanded"
[ngClass]="item.cssClass"
cdkAccordionItem #cdkAccordionItem="cdkAccordionItem"
[expanded]="item.expanded">
<header (click)="onToggle(cdkAccordionItem, section)" class="e2e-accordion-item-header">
<div>
<ng-container *ngTemplateOutlet="item.template"></ng-container>
</div>
<button class="material-icons e2e-toggle"
[class.e2e-expand]="!cdkAccordionItem.expanded"
[class.e2e-collapse]="cdkAccordionItem.expanded">
{{cdkAccordionItem.expanded ? 'expand_less' : 'expand_more'}}
</button>
</header>
<section *ngIf="cdkAccordionItem.expanded" @enter>
<ng-container *ngTemplateOutlet="item.panel"></ng-container>
</section>
</section>
</div>
</div>
</sci-viewport>
<div cdkAccordion [multi]="multi" class="accordion">
<section *ngFor="let item of items; trackBy: trackByFn"
class="accordion-item e2e-accordion-item"
[class.e2e-expanded]="cdkAccordionItem.expanded"
[ngClass]="item.cssClass"
cdkAccordionItem #cdkAccordionItem="cdkAccordionItem"
[expanded]="item.expanded">
<header (click)="onToggle(cdkAccordionItem)" class="e2e-accordion-item-header">
<div>
<ng-container *ngTemplateOutlet="item.template"></ng-container>
</div>
<button class="material-icons e2e-toggle"
[class.e2e-expand]="!cdkAccordionItem.expanded"
[class.e2e-collapse]="cdkAccordionItem.expanded">
{{cdkAccordionItem.expanded ? 'expand_less' : 'expand_more'}}
</button>
</header>
<section *ngIf="cdkAccordionItem.expanded" @enter>
<ng-container *ngTemplateOutlet="item.panel"></ng-container>
</section>
</section>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,34 @@ $border-color: var(--sci-color-P400);
$background-color: var(--sci-color-P100);

:host {
display: grid;
display: block;
border: 1px solid var(--sci-color-P400);
border-radius: 5px;

> sci-viewport div.accordion-client {
// Collapse bottom borders: Render a bottom border only if the accordion items do not fill available space
&:not(.filled) > section.accordion-item:last-child {
border-bottom: 1px solid var(--sci-color-P400);
}
// Collapse bottom borders: Render a bottom border only if the accordion items do not fill available space
&:not(.filled) section.accordion-item:last-child {
border-bottom: 1px solid var(--sci-color-P400);
}

> section.accordion-item {
padding: 1em;
section.accordion-item {
padding: 1em;

&:not(:first-child) {
border-top: 1px solid var(--sci-color-P400);
}
&:not(:first-child) {
border-top: 1px solid var(--sci-color-P400);
}

> header {
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
user-select: none;
}
> header {
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
user-select: none;
}

> section {
display: grid; // public API
grid-template-columns: 100%;
gap: .5em;
}
> section {
display: grid; // public API
grid-template-columns: 100%;
gap: .5em;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
* SPDX-License-Identifier: EPL-2.0
*/

import { Component, ContentChildren, HostBinding, Input, QueryList, TrackByFunction, ViewChild } from '@angular/core';
import { Component, ContentChildren, ElementRef, HostBinding, Input, OnDestroy, OnInit, QueryList, TrackByFunction, ViewChild } from '@angular/core';
import { animate, AnimationMetadata, style, transition, trigger } from '@angular/animations';
import { SciAccordionItemDirective } from './accordion-item.directive';
import { SciViewportComponent } from '@scion/toolkit/viewport';
import { CdkAccordionItem } from '@angular/cdk/accordion';
import { CdkAccordion, CdkAccordionItem } from '@angular/cdk/accordion';
import { fromDimension$ } from '@scion/toolkit/observable';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { combineLatest, Subject } from 'rxjs';

/**
* Component that shows items in an accordion.
Expand Down Expand Up @@ -47,7 +49,12 @@ import { CdkAccordionItem } from '@angular/cdk/accordion';
trigger('enter', SciAccordionComponent.provideEnterAnimation()),
],
})
export class SciAccordionComponent {
export class SciAccordionComponent implements OnInit, OnDestroy {

private _destroy$ = new Subject<void>();

@ViewChild(CdkAccordion, {static: true, read: ElementRef})
private _cdkAccordion: ElementRef<HTMLElement>;

@HostBinding('class.bubble')
public get isBubbleVariant(): boolean {
Expand All @@ -59,8 +66,8 @@ export class SciAccordionComponent {
return this.variant === 'solid';
}

@ViewChild(SciViewportComponent, {static: true})
private _viewport: SciViewportComponent;
@HostBinding('class.filled')
public filled: boolean;

@ContentChildren(SciAccordionItemDirective)
public items: QueryList<SciAccordionItemDirective>;
Expand All @@ -77,13 +84,42 @@ export class SciAccordionComponent {
@Input()
public variant: 'solid' | 'bubble' = 'bubble';

constructor(private _host: ElementRef<HTMLElement>) {
}

public ngOnInit(): void {
this.computeFilledStateOnDimensionChange();
}

public trackByFn: TrackByFunction<SciAccordionItemDirective> = (index: number, item: SciAccordionItemDirective): any => {
return item.key || item;
};

public onToggle(item: CdkAccordionItem, section: HTMLElement): void {
public onToggle(item: CdkAccordionItem): void {
item.toggle();
item.expanded && setTimeout(() => this._viewport.scrollIntoView(section));
}

/**
* Computes whether this accordion fills the boundaries of this component.
* It does this on each dimension change and sets the CSS class 'filled'
* accordingly.
*/
private computeFilledStateOnDimensionChange(): void {
combineLatest([
fromDimension$(this._host.nativeElement),
fromDimension$(this._cdkAccordion.nativeElement),
])
.pipe(
debounceTime(5), // debounce dimension changes because the animation for expanding/collapsing a panel continuously emits resize events.
takeUntil(this._destroy$),
)
.subscribe(([hostDimension, accordionDimension]) => {
this.filled = (hostDimension.clientHeight <= accordionDimension.offsetHeight);
});
}

public ngOnDestroy(): void {
this._destroy$.next();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SciViewportModule } from '@scion/toolkit/viewport';
import { SciAccordionComponent } from './accordion.component';
import { SciAccordionItemDirective } from './accordion-item.directive';
import { CdkAccordionModule } from '@angular/cdk/accordion';
Expand All @@ -26,7 +25,6 @@ import { SciDimensionModule } from '@scion/toolkit/dimension';
],
imports: [
CommonModule,
SciViewportModule,
CdkAccordionModule,
SciDimensionModule,
],
Expand Down

0 comments on commit ff0aac3

Please sign in to comment.