Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Added activeIndex class to repeater #51

Merged
merged 15 commits into from
Jul 26, 2019
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions e2e/repeater.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ import {
} from '@skyux-sdk/e2e';

describe('Repeater', () => {
it('should match the baseline sort screenshot', (done) => {
SkyHostBrowser.get('visual/sort');
Blackbaud-SteveBrush marked this conversation as resolved.
Show resolved Hide resolved
SkyHostBrowser.setWindowBreakpoint('lg');
SkyHostBrowser.scrollTo('#screenshot-sort-full');
expect('#screenshot-sort-full').toMatchBaselineScreenshot(done, {
screenshotName: 'sort'
});
});

it('should match previous repeater screenshot', (done) => {
SkyHostBrowser.get('visual/repeater');
SkyHostBrowser.setWindowBreakpoint('lg');
Expand All @@ -22,6 +13,15 @@ describe('Repeater', () => {
});
});

it('should match previous repeater screenshot when an item is active', (done) => {
SkyHostBrowser.get('visual/repeater');
SkyHostBrowser.setWindowBreakpoint('lg');
SkyHostBrowser.scrollTo('#screenshot-repeater-with-active-item');
expect('#screenshot-repeater-with-active-item').toMatchBaselineScreenshot(done, {
screenshotName: 'repeater-with-active-item'
});
});

it('should match previous repeater screenshot when all are collapsed', (done) => {
SkyHostBrowser.get('visual/repeater');
SkyHostBrowser.setWindowBreakpoint('lg');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<sky-repeater [expandMode]="expandMode">
<sky-repeater
[activeIndex]="activeIndex"
[expandMode]="expandMode"
>
<sky-repeater-item
(collapse)="onCollapse()"
(expand)="onExpand()"
Expand All @@ -16,7 +19,10 @@
<sky-repeater-item-title>Title 2</sky-repeater-item-title>
<sky-repeater-item-content>Content 2</sky-repeater-item-content>
</sky-repeater-item>
<sky-repeater-item *ngIf="!removeLastItem" [isExpanded]="lastItemExpanded" [isSelected]="lastItemSelected">
<sky-repeater-item *ngIf="!removeLastItem"
[isExpanded]="lastItemExpanded"
[isSelected]="lastItemSelected"
>
<sky-repeater-item-context-menu *ngIf="showContextMenu">
a
</sky-repeater-item-context-menu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ import {
templateUrl: './repeater.component.fixture.html'
})
export class RepeaterTestComponent {
@ViewChild(SkyRepeaterComponent)
public repeater: SkyRepeaterComponent;

public showContextMenu: boolean;

public removeLastItem: boolean;
public activeIndex: number = undefined;

public expandMode = 'single';

public lastItemExpanded: boolean;

public lastItemSelected = false;

public removeLastItem: boolean;

public showContextMenu: boolean;

@ViewChild(SkyRepeaterComponent)
public repeater: SkyRepeaterComponent;

public onCollapse(): void {}

public onExpand(): void {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<div
class="sky-repeater-item sky-padding-even-default"
[ngClass]="{
'sky-repeater-item-active': isActive,
'sky-repeater-item-collapsible': isCollapsible,
'sky-repeater-item-selected': isSelected
}"
Expand Down
7 changes: 7 additions & 0 deletions src/app/public/modules/repeater/repeater-item.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
padding-top:10px;
}
}

&.sky-repeater-item-active {
background-color: $sky-background-color-neutral-light;
color: $sky-text-color-default;
padding-left: 6px;
border-left: $sky-nav-selected-border-width solid $sky-highlight-color-info;
}
Copy link
Contributor Author

@Blackbaud-AlexKingman Blackbaud-AlexKingman Jul 17, 2019

Choose a reason for hiding this comment

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

}

.sky-repeater-item-left {
Expand Down
82 changes: 55 additions & 27 deletions src/app/public/modules/repeater/repeater-item.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
TemplateRef
} from '@angular/core';
Expand All @@ -25,65 +26,67 @@ import {
SkyInlineFormConfig
} from '@skyux/inline-form';

import {
Subject
} from 'rxjs/Subject';

import {
SkyRepeaterService
} from './repeater.service';

let nextId: number = 0;
let nextContentId: number = 0;

@Component({
selector: 'sky-repeater-item',
styleUrls: ['./repeater-item.component.scss'],
templateUrl: './repeater-item.component.html',
animations: [skyAnimationSlide]
})
export class SkyRepeaterItemComponent implements OnDestroy {
public contentId: string = `sky-radio-content-${++nextId}`;
export class SkyRepeaterItemComponent implements OnDestroy, OnInit {

public get isExpanded(): boolean {
return this._isExpanded;
}
@Input()
public inlineFormConfig: SkyInlineFormConfig;

@Input()
public inlineFormTemplate: TemplateRef<any>;

@Input()
public set isExpanded(value: boolean) {
this.updateForExpanded(value, true);
}

public get isSelected(): boolean {
return this._isSelected;
public get isExpanded(): boolean {
return this._isExpanded;
}

@Input()
public set isSelected(value: boolean) {
this._isSelected = value;
}

@Input()
public showInlineForm: boolean = false;

@Input()
public inlineFormConfig: SkyInlineFormConfig;
public get isSelected(): boolean {
return this._isSelected;
}

@Input()
public inlineFormTemplate: TemplateRef<any>;

@Output()
public inlineFormClose = new EventEmitter<SkyInlineFormCloseArgs>();
public selectable: boolean = false;

@Input()
public selectable: boolean = false;
public showInlineForm: boolean = false;

@Output()
public collapse = new EventEmitter<void>();

@Output()
public expand = new EventEmitter<void>();

public slideDirection: string;
@Output()
public inlineFormClose = new EventEmitter<SkyInlineFormCloseArgs>();

public contentId: string = `sky-radio-content-${++nextContentId}`;

public isActive: boolean = false;

public get isCollapsible(): boolean {
return this._isCollapsible;
}
public set isCollapsible(value: boolean) {
if (this.isCollapsible !== value) {
this._isCollapsible = value;
Expand All @@ -95,6 +98,14 @@ export class SkyRepeaterItemComponent implements OnDestroy {
}
}

public get isCollapsible(): boolean {
return this._isCollapsible;
}

public slideDirection: string;

private ngUnsubscribe = new Subject<void>();

private _isCollapsible = true;

private _isExpanded = true;
Expand All @@ -109,23 +120,40 @@ export class SkyRepeaterItemComponent implements OnDestroy {
this.slideForExpanded(false);
}

public ngOnInit(): void {
setTimeout(() => {
this.repeaterService.registerItem(this);
this.repeaterService.activeItemChange
.takeUntil(this.ngUnsubscribe)
.subscribe((item: SkyRepeaterItemComponent) => {
this.isActive = this === item;
this.changeDetector.markForCheck();
});
});
}

public ngOnDestroy(): void {
this.collapse.complete();
this.expand.complete();
this.inlineFormClose.complete();

this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();

this.repeaterService.unregisterItem(this);
}

public headerClick() {
public headerClick(): void {
if (this.isCollapsible) {
this.updateForExpanded(!this.isExpanded, true);
}
}

public chevronDirectionChange(direction: string) {
public chevronDirectionChange(direction: string): void {
this.updateForExpanded(direction === 'up', true);
}

public updateForExpanded(value: boolean, animate: boolean) {
public updateForExpanded(value: boolean, animate: boolean): void {
if (this.isCollapsible === false && value === false) {
this.logService.warn(
`Setting isExpanded to false when the repeater item is not collapsible
Expand All @@ -146,15 +174,15 @@ export class SkyRepeaterItemComponent implements OnDestroy {
}
}

public updateIsSelected(value: SkyCheckboxChange) {
public updateIsSelected(value: SkyCheckboxChange): void {
this._isSelected = value.checked;
}

public onInlineFormClose(inlineFormCloseArgs: SkyInlineFormCloseArgs): void {
this.inlineFormClose.emit(inlineFormCloseArgs);
}

private slideForExpanded(animate: boolean) {
private slideForExpanded(animate: boolean): void {
this.slideDirection = this.isExpanded ? 'down' : 'up';
}
}
51 changes: 51 additions & 0 deletions src/app/public/modules/repeater/repeater.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,57 @@ describe('Repeater item component', () => {
}));
});

describe('with activeIndex', () => {
let fixture: ComponentFixture<RepeaterTestComponent>;
let cmp: RepeaterTestComponent;
let el: any;

beforeEach(() => {
fixture = TestBed.createComponent(RepeaterTestComponent);
cmp = fixture.componentInstance;
el = fixture.nativeElement;
});

function getItems(): HTMLElement[] {
return el.querySelectorAll('.sky-repeater-item');
}

it('should show active item if activeIndex is set on init', fakeAsync(() => {
cmp.activeIndex = 0;
fixture.detectChanges();
tick();
fixture.detectChanges();
tick();

let activeRepeaterItem = el.querySelectorAll('.sky-repeater-item-active');
expect(activeRepeaterItem.length).toBe(1);
}));

it('should add and remove active css class when activeIndex value changes', fakeAsync(() => {
fixture.detectChanges();
tick();

let activeRepeaterItem = el.querySelectorAll('.sky-repeater-item-active');
expect(activeRepeaterItem.length).toBe(0);

cmp.activeIndex = 0;
fixture.detectChanges();
tick();

activeRepeaterItem = el.querySelectorAll('.sky-repeater-item-active');
expect(activeRepeaterItem.length).toBe(1);
const items = getItems();
expect(items[0]).toHaveCssClass('sky-repeater-item-active');

cmp.activeIndex = undefined;
fixture.detectChanges();
tick();

activeRepeaterItem = el.querySelectorAll('.sky-repeater-item-active');
expect(activeRepeaterItem.length).toBe(0);
}));
});

describe('with inline-form', () => {
let fixture: ComponentFixture<RepeaterInlineFormFixtureComponent>;
let el: HTMLElement;
Expand Down
Loading