Skip to content

Commit 1c290a2

Browse files
jnizeticfantv
authored andcommitted
feat(accordion): add config service to provide default values
refs #518 Closes #655
1 parent 99d4386 commit 1c290a2

File tree

12 files changed

+146
-15
lines changed

12 files changed

+146
-15
lines changed

demo/src/app/components/accordion/accordion.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {DEMO_SNIPPETS} from './demos';
1010
<ngbd-api-docs directive="NgbPanelTitle"></ngbd-api-docs>
1111
<ngbd-api-docs directive="NgbPanelContent"></ngbd-api-docs>
1212
<ngbd-api-docs-class type="NgbPanelChangeEvent"></ngbd-api-docs-class>
13+
<ngbd-api-docs-config type="NgbAccordionConfig"></ngbd-api-docs-config>
1314
<ngbd-example-box demoTitle="Accordion" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
1415
<ngbd-accordion-basic></ngbd-accordion-basic>
1516
</ngbd-example-box>
@@ -23,6 +24,11 @@ import {DEMO_SNIPPETS} from './demos';
2324
[tsSnippet]="snippets.preventChange.code">
2425
<ngbd-accordion-preventchange></ngbd-accordion-preventchange>
2526
</ngbd-example-box>
27+
<ngbd-example-box demoTitle="Global configuration of accordions"
28+
[htmlSnippet]="snippets.config.markup"
29+
[tsSnippet]="snippets.config.code">
30+
<ngbd-accordion-config></ngbd-accordion-config>
31+
</ngbd-example-box>
2632
</ngbd-content-wrapper>
2733
`
2834
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<p>This accordion uses customized default values.</p>
2+
3+
<ngb-accordion #acc="ngbAccordion" activeIds="config-panel-one">
4+
<ngb-panel title="One" id="config-panel-one">
5+
<template ngbPanelContent>
6+
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia
7+
aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor,
8+
sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica,
9+
craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings
10+
occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
11+
labore sustainable VHS.
12+
</template>
13+
</ngb-panel>
14+
<ngb-panel title="Two">
15+
<template ngbPanelContent>
16+
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia
17+
aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor,
18+
sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica,
19+
craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings
20+
occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
21+
labore sustainable VHS.
22+
</template>
23+
</ngb-panel>
24+
</ngb-accordion>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {Component} from '@angular/core';
2+
import {NgbAccordionConfig} from '@ng-bootstrap/ng-bootstrap';
3+
4+
@Component({
5+
selector: 'ngbd-accordion-config',
6+
templateUrl: './accordion-config.html',
7+
providers: [NgbAccordionConfig] // add the NgbAccordionConfig to the component providers
8+
})
9+
export class NgbdAccordionConfig {
10+
constructor(config: NgbAccordionConfig) {
11+
// customize default values of accordions used by this component tree
12+
config.closeOthers = true;
13+
config.type = 'info';
14+
}
15+
}

demo/src/app/components/accordion/demos/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import {NgbdAccordionBasic} from './basic/accordion-basic';
22
import {NgbdAccordionPreventchange} from './preventchange/accordion-preventchange';
33
import {NgbdAccordionStatic} from './static/accordion-static';
44
import {NgbdAccordionToggle} from './toggle/accordion-toggle';
5+
import {NgbdAccordionConfig} from './config/accordion-config';
56

67
export const DEMO_DIRECTIVES =
7-
[NgbdAccordionBasic, NgbdAccordionPreventchange, NgbdAccordionStatic, NgbdAccordionToggle];
8+
[NgbdAccordionBasic, NgbdAccordionPreventchange, NgbdAccordionStatic, NgbdAccordionToggle, NgbdAccordionConfig];
89

910
export const DEMO_SNIPPETS = {
1011
basic: {
@@ -22,5 +23,9 @@ export const DEMO_SNIPPETS = {
2223
toggle: {
2324
code: require('!!prismjs?lang=typescript!./toggle/accordion-toggle'),
2425
markup: require('!!prismjs?lang=markup!./toggle/accordion-toggle.html')
26+
},
27+
config: {
28+
code: require('!!prismjs?lang=typescript!./config/accordion-config'),
29+
markup: require('!!prismjs?lang=markup!./config/accordion-config.html')
2530
}
2631
};

demo/src/app/components/shared/api-docs/api-docs.component.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,12 @@ export class NgbdApiDocs {
3838
};
3939

4040
/**
41-
* Returns the default value of the given directive input. If falsy, returns the default value of the matching
42-
* config service property
41+
* Returns the default value of the given directive input by first looking for it in the matching config service
42+
* property. If there is no matching config property, it reads it from the input.
4343
*/
4444
defaultInputValue(input: InputDesc): string {
45-
if (input.defaultValue !== undefined) {
46-
return input.defaultValue;
47-
}
48-
4945
const configProperty = this._configProperties[input.name];
50-
return (configProperty && configProperty.defaultValue);
46+
return configProperty ? configProperty.defaultValue : input.defaultValue;
5147
}
5248

5349
/**
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {NgbAccordionConfig} from './accordion-config';
2+
3+
describe('ngb-accordion-config', () => {
4+
it('should have sensible default values', () => {
5+
const config = new NgbAccordionConfig();
6+
7+
expect(config.closeOthers).toBe(false);
8+
expect(config.type).toBeUndefined();
9+
});
10+
});

src/accordion/accordion-config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {Injectable} from '@angular/core';
2+
3+
/**
4+
* Configuration service for the NgbAccordion component.
5+
* You can inject this service, typically in your root component, and customize the values of its properties in
6+
* order to provide default values for all the accordions used in the application.
7+
*/
8+
@Injectable()
9+
export class NgbAccordionConfig {
10+
closeOthers = false;
11+
type: string;
12+
}

src/accordion/accordion.module.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ import {NgModule} from '@angular/core';
22
import {CommonModule} from '@angular/common';
33

44
import {NGB_ACCORDION_DIRECTIVES} from './accordion';
5+
import {NgbAccordionConfig} from './accordion-config';
56

67
export {NgbPanelChangeEvent} from './accordion';
8+
export {NgbAccordionConfig} from './accordion-config';
79

8-
@NgModule({declarations: NGB_ACCORDION_DIRECTIVES, exports: NGB_ACCORDION_DIRECTIVES, imports: [CommonModule]})
10+
@NgModule({
11+
declarations: NGB_ACCORDION_DIRECTIVES,
12+
exports: NGB_ACCORDION_DIRECTIVES,
13+
imports: [CommonModule],
14+
providers: [NgbAccordionConfig]
15+
})
916
export class NgbAccordionModule {
1017
}

src/accordion/accordion.spec.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import {TestBed, ComponentFixture} from '@angular/core/testing';
1+
import {TestBed, ComponentFixture, inject} from '@angular/core/testing';
22
import {createGenericTestComponent} from '../util/tests';
33

44
import {Component} from '@angular/core';
55

66
import {NgbAccordionModule} from './accordion.module';
7+
import {NgbAccordionConfig} from './accordion-config';
8+
import {NgbAccordion} from './accordion';
79

810
const createTestComponent = (html: string) =>
911
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
@@ -45,6 +47,13 @@ describe('ngb-accordion', () => {
4547
TestBed.overrideComponent(TestComponent, {set: {template: html}});
4648
});
4749

50+
it('should initialize inputs with default values', () => {
51+
const defaultConfig = new NgbAccordionConfig();
52+
const accordionCmp = new NgbAccordion(defaultConfig);
53+
expect(accordionCmp.type).toBe(defaultConfig.type);
54+
expect(accordionCmp.closeOtherPanels).toBe(defaultConfig.closeOthers);
55+
});
56+
4857
it('should have no open panels', () => {
4958
const fixture = TestBed.createComponent(TestComponent);
5059
fixture.detectChanges();
@@ -303,6 +312,47 @@ describe('ngb-accordion', () => {
303312
expect(el[1]).toHaveCssClass('card-danger');
304313
expect(el[2]).toHaveCssClass('card-warning');
305314
});
315+
316+
describe('Custom config', () => {
317+
let config: NgbAccordionConfig;
318+
319+
beforeEach(() => { TestBed.configureTestingModule({imports: [NgbAccordionModule]}); });
320+
321+
beforeEach(inject([NgbAccordionConfig], (c: NgbAccordionConfig) => {
322+
config = c;
323+
config.closeOthers = true;
324+
config.type = 'success';
325+
}));
326+
327+
it('should initialize inputs with provided config', () => {
328+
const fixture = TestBed.createComponent(NgbAccordion);
329+
fixture.detectChanges();
330+
331+
let accordion = fixture.componentInstance;
332+
expect(accordion.closeOtherPanels).toBe(config.closeOthers);
333+
expect(accordion.type).toBe(config.type);
334+
});
335+
});
336+
337+
describe('Custom config as provider', () => {
338+
let config = new NgbAccordionConfig();
339+
config.closeOthers = true;
340+
config.type = 'success';
341+
342+
beforeEach(() => {
343+
TestBed.configureTestingModule(
344+
{imports: [NgbAccordionModule], providers: [{provide: NgbAccordionConfig, useValue: config}]});
345+
});
346+
347+
it('should initialize inputs with provided config as provider', () => {
348+
const fixture = TestBed.createComponent(NgbAccordion);
349+
fixture.detectChanges();
350+
351+
let accordion = fixture.componentInstance;
352+
expect(accordion.closeOtherPanels).toBe(config.closeOthers);
353+
expect(accordion.type).toBe(config.type);
354+
});
355+
});
306356
});
307357

308358
@Component({selector: 'test-cmp', template: ''})

src/accordion/accordion.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
AfterContentChecked
1212
} from '@angular/core';
1313
import {isString} from '../util/util';
14+
import {NgbAccordionConfig} from './accordion-config';
1415

1516
let nextId = 0;
1617

@@ -115,7 +116,7 @@ export class NgbAccordion implements AfterContentChecked {
115116
/**
116117
* Whether the other panels should be closed when a panel is opened
117118
*/
118-
@Input('closeOthers') closeOtherPanels = false;
119+
@Input('closeOthers') closeOtherPanels: boolean;
119120

120121
/**
121122
* Type of accordion's panels. Bootstrap 4 recognizes the following types: "success", "info", "warning" and "danger".
@@ -138,6 +139,11 @@ export class NgbAccordion implements AfterContentChecked {
138139
*/
139140
private _panelRefs: Map<string, NgbPanel> = new Map<string, NgbPanel>();
140141

142+
constructor(config: NgbAccordionConfig) {
143+
this.type = config.type;
144+
this.closeOtherPanels = config.closeOthers;
145+
}
146+
141147
/**
142148
* Programmatically toggle a panel with a given id.
143149
*/

0 commit comments

Comments
 (0)