Skip to content

Commit

Permalink
feat(accordion): make isOpen two way bindable
Browse files Browse the repository at this point in the history
  • Loading branch information
steelsojka committed Sep 14, 2017
1 parent b721041 commit c12d6b9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 26 deletions.
17 changes: 14 additions & 3 deletions src/accordion/accordion-group.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class AccordionPanelComponent implements OnInit, OnDestroy {
/** if <code>true</code> — disables accordion group */
@Input() isDisabled: boolean;
/** Emits when the opened state changes */
@Output() public isOpenChanges: EventEmitter<boolean> = new EventEmitter();
@Output() isOpenChange: EventEmitter<boolean> = new EventEmitter();

// Questionable, maybe .panel-open should be on child div.panel element?
/** Is accordion group open or closed */
Expand All @@ -42,7 +42,6 @@ export class AccordionPanelComponent implements OnInit, OnDestroy {

set isOpen(value: boolean) {
this._isOpen = value;
this.isOpenChanges.emit(this.isOpen);

if (value) {
this.accordion.closeOtherPanels(this);
Expand All @@ -69,9 +68,21 @@ export class AccordionPanelComponent implements OnInit, OnDestroy {
this.accordion.removeGroup(this);
}


toggleOpen(event: Event): any {
if (!this.isDisabled) {
this.isOpen = !this.isOpen;
this.setOpenState(!this.isOpen);
}
}

/**
* Sets the isOpen state internally
* @param {boolean} isOpen
*/
setOpenState(isOpen: boolean): void {
if (isOpen !== this._isOpen) {
this._isOpen = isOpen;
this.isOpenChange.emit(this._isOpen);
}
}
}
2 changes: 1 addition & 1 deletion src/accordion/accordion.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class AccordionComponent {

this.groups.forEach((group: AccordionPanelComponent) => {
if (group !== openGroup) {
group.isOpen = false;
group.setOpenState(false);
}
});
}
Expand Down
41 changes: 19 additions & 22 deletions src/spec/accordion.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { AccordionModule } from '../accordion/accordion.module';
class TestAccordionComponent {
oneAtATime = true;
panels: any[] = [
{isOpen: false, isDisabled: false, isOpenChangesValue: null},
{isOpen: false, isDisabled: false, isOpenChangesValue: null},
{isOpen: false, isDisabled: false, isOpenChangesValue: null}
{isOpen: false, isDisabled: false},
{isOpen: false, isDisabled: false},
{isOpen: false, isDisabled: false}
];

constructor(config: AccordionConfig) {
Expand All @@ -25,23 +25,20 @@ const html = `
<accordion [closeOthers]="oneAtATime">
<accordion-group heading="Panel 1"
[isOpen]="panels[0].isOpen"
[isDisabled]="panels[0].isDisabled"
(isOpenChanges)="panels[0].isOpenChangesValue = $event">
[(isOpen)]="panels[0].isOpen"
[isDisabled]="panels[0].isDisabled">
Content of panel 1
</accordion-group>
<accordion-group heading="Panel 2"
[isOpen]="panels[1].isOpen"
[isDisabled]="panels[1].isDisabled"
(isOpenChanges)="panels[1].isOpenChangesValue = $event">
[(isOpen)]="panels[1].isOpen"
[isDisabled]="panels[1].isDisabled">
Content of panel 2
</accordion-group>
<accordion-group heading="Panel 3"
[isOpen]="panels[2].isOpen"
[isDisabled]="panels[2].isDisabled"
(isOpenChanges)="panels[2].isOpenChangesValue = $event">
[(isOpen)]="panels[2].isOpen"
[isDisabled]="panels[2].isDisabled">
Content of panel 3
</accordion-group>
Expand Down Expand Up @@ -170,28 +167,28 @@ describe('Component: Accordion', () => {
expectOpenPanels(element, [false, false, false]);
});

it('should output the open state when it is changed internally', () => {
it('should modify the parent isOpen state when changed internally (2 way binding)', () => {
const headingLinks = element.querySelectorAll('.accordion-toggle');

// Clicking (internal state modified)
headingLinks[0].click();
fixture.detectChanges();
expect(context.panels[0].isOpenChangesValue).toBe(true);
expect(context.panels[1].isOpenChangesValue).toBe(false);
expect(context.panels[2].isOpenChangesValue).toBe(false);
expect(context.panels[0].isOpen).toBe(true);
expect(context.panels[1].isOpen).toBe(false);
expect(context.panels[2].isOpen).toBe(false);

// State modified by parent component
headingLinks[2].click();
fixture.detectChanges();
expect(context.panels[0].isOpenChangesValue).toBe(false);
expect(context.panels[1].isOpenChangesValue).toBe(false);
expect(context.panels[2].isOpenChangesValue).toBe(true);
expect(context.panels[0].isOpen).toBe(false);
expect(context.panels[1].isOpen).toBe(false);
expect(context.panels[2].isOpen).toBe(true);

// Modified by binding
context.panels[1].isOpen = true;
fixture.detectChanges();
expect(context.panels[0].isOpenChangesValue).toBe(false);
expect(context.panels[1].isOpenChangesValue).toBe(true);
expect(context.panels[2].isOpenChangesValue).toBe(false);
expect(context.panels[0].isOpen).toBe(false);
expect(context.panels[1].isOpen).toBe(true);
expect(context.panels[2].isOpen).toBe(false);
});
});

0 comments on commit c12d6b9

Please sign in to comment.