Skip to content

Commit

Permalink
feat(accordion): export NgbAccordionItem directive to the template (#…
Browse files Browse the repository at this point in the history
…4479)

It can be accessed from the template via `<div ngbAccordionItem #item = 'ngbAccordionItem'>` and used for:
* rendering like `{{ item.collapsed }}`, `{{ item.disabled }}`, `{{ item.id }}`
* triggering state change via `item.collapsed = true`, `item.toggle()`, `item.disabled = false`
  • Loading branch information
maxokorokov committed Mar 21, 2023
1 parent f1eefe0 commit c0c6358
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
58 changes: 58 additions & 0 deletions src/accordion/accordion.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,64 @@ describe('ngb-accordion directive', () => {
expect(toggleButtons[0].disabled).toBeTruthy();
});

it(`should allow using 'ngbAccordionItem' from the template`, () => {
const fixture = createTestComponent(
`<div ngbAccordion>
<div ngbAccordionItem='item' #item='ngbAccordionItem' [collapsed]='false'>
<h2 ngbAccordionHeader>
<button ngbAccordionButton>{{ item.collapsed ? 'collapsed-' : 'expanded-' }}{{ item.disabled ? 'disabled' : 'enabled' }}</button>
</h2>
<div ngbAccordionCollapse><div ngbAccordionBody></div></div>
</div>
</div>
<button id="btn-toggle" (click)='item.toggle()'></button>
<button id="btn-expand" (click)='item.collapsed = false'></button>
<button id="btn-disable" (click)='item.disabled = true'></button>`,
);

const el = fixture.nativeElement;

// initial state
expect(getPanelsTitle(el)).toEqual(['expanded-enabled']);

// toggling via item.toggle()
el.querySelector('#btn-toggle').click();
fixture.detectChanges();
expect(getPanelsTitle(el)).toEqual(['collapsed-enabled']);

// expanding via item.collapsed = false
el.querySelector('#btn-expand').click();
fixture.detectChanges();
expect(getPanelsTitle(el)).toEqual(['expanded-enabled']);

// changing disabled state via item.disabled = true
el.querySelector('#btn-disable').click();
fixture.detectChanges();
expect(getPanelsTitle(el)).toEqual(['expanded-disabled']);
});

it(`should allow using 'ngbAccordionItem' from the template in a loop`, () => {
const fixture = createTestComponent(
`<div ngbAccordion>
<div ngbAccordionItem #item='ngbAccordionItem' *ngFor='let i of items' [collapsed]='i.collapsed' [disabled]='i.disabled'>
<h2 ngbAccordionHeader>
<button ngbAccordionButton>{{ item.collapsed ? 'collapsed-' : 'expanded-' }}{{ item.disabled ? 'disabled' : 'enabled' }}</button>
</h2>
<div ngbAccordionCollapse><div ngbAccordionBody></div></div>
</div>
</div>`,
);
const el = fixture.nativeElement;

expect(getPanelsTitle(el)).toEqual(['collapsed-enabled', 'collapsed-enabled', 'collapsed-enabled']);

fixture.componentInstance.items[1].disabled = true;
fixture.componentInstance.items[0].collapsed = false;
fixture.detectChanges();

expect(getPanelsTitle(el)).toEqual(['expanded-enabled', 'collapsed-disabled', 'collapsed-enabled']);
});

it('should emit panel events when toggling panels', () => {
const fixture = TestBed.createComponent(TestComponent);
const el = fixture.nativeElement;
Expand Down
13 changes: 10 additions & 3 deletions src/accordion/accordion.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,19 @@ export class NgbAccordionButton {
'[class.accordion-header]': 'true',
},
})
export class NgbAccordionHeader {
constructor() {}
}
export class NgbAccordionHeader {}

/**
* A directive that wraps an accordion item: a toggleable header + body that collapses.
*
* You can get hold of the `NgbAccordionItem` instance by using the `#item="ngbAccordionItem"`.
* It provides some useful properties and methods about a single item: ex. whether it is collapsed or disabled.
*
* Every accordion item has a string ID that is automatically generated, unless provided explicitly.
*/
@Directive({
selector: '[ngbAccordionItem]',
exportAs: 'ngbAccordionItem',
standalone: true,
host: {
'[class.accordion-item]': 'true',
Expand Down

0 comments on commit c0c6358

Please sign in to comment.