Skip to content

Commit

Permalink
feat(dropdown): add config service to provide default values
Browse files Browse the repository at this point in the history
refs #518

Closes #688
  • Loading branch information
jnizet authored and pkozlowski-opensource committed Sep 7, 2016
1 parent a58588c commit e97d260
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 6 deletions.
10 changes: 10 additions & 0 deletions demo/src/app/components/dropdown/demos/config/dropdown-config.html
@@ -0,0 +1,10 @@
<p>This dropdown uses customized default values.</p>

<div ngbDropdown>
<button class="btn btn-outline-primary" id="dropdownMenu3" ngbDropdownToggle>Toggle</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu3">
<button class="dropdown-item">Action - 1</button>
<button class="dropdown-item">Another Action</button>
<button class="dropdown-item">Something else is here</button>
</div>
</div>
15 changes: 15 additions & 0 deletions demo/src/app/components/dropdown/demos/config/dropdown-config.ts
@@ -0,0 +1,15 @@
import {Component} from '@angular/core';
import {NgbDropdownConfig} from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'ngbd-dropdown-config',
templateUrl: './dropdown-config.html',
providers: [NgbDropdownConfig] // add NgbDropdownConfig to the component providers
})
export class NgbdDropdownConfig {
constructor(config: NgbDropdownConfig) {
// customize default values of dropdowns used by this component tree
config.up = true;
config.autoClose = false;
}
}
10 changes: 8 additions & 2 deletions demo/src/app/components/dropdown/demos/index.ts
@@ -1,9 +1,15 @@
import {NgbdDropdownBasic} from './basic/dropdown-basic';
import {NgbdDropdownConfig} from './config/dropdown-config';

export const DEMO_DIRECTIVES = [NgbdDropdownBasic];
export const DEMO_DIRECTIVES = [NgbdDropdownBasic, NgbdDropdownConfig];

export const DEMO_SNIPPETS = {
basic: {
code: require('!!prismjs?lang=typescript!./basic/dropdown-basic'),
markup: require('!!prismjs?lang=markup!./basic/dropdown-basic.html')}
markup: require('!!prismjs?lang=markup!./basic/dropdown-basic.html')
},
config: {
code: require('!!prismjs?lang=typescript!./config/dropdown-config'),
markup: require('!!prismjs?lang=markup!./config/dropdown-config.html')
}
};
6 changes: 6 additions & 0 deletions demo/src/app/components/dropdown/dropdown.component.ts
Expand Up @@ -7,9 +7,15 @@ import {DEMO_SNIPPETS} from './demos';
<ngbd-content-wrapper component="Dropdown">
<ngbd-api-docs directive="NgbDropdown"></ngbd-api-docs>
<ngbd-api-docs directive="NgbDropdownToggle"></ngbd-api-docs>
<ngbd-api-docs-config type="NgbDropdownConfig"></ngbd-api-docs-config>
<ngbd-example-box demoTitle="Dropdown" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
<ngbd-dropdown-basic></ngbd-dropdown-basic>
</ngbd-example-box>
<ngbd-example-box demoTitle="Global configuration of dropdowns"
[htmlSnippet]="snippets.config.markup"
[tsSnippet]="snippets.config.code">
<ngbd-dropdown-config></ngbd-dropdown-config>
</ngbd-example-box>
</ngbd-content-wrapper>
`
})
Expand Down
10 changes: 10 additions & 0 deletions src/dropdown/dopdown-config.spec.ts
@@ -0,0 +1,10 @@
import {NgbDropdownConfig} from './dropdown-config';

describe('ngb-dropdown-config', () => {
it('should have sensible default values', () => {
const config = new NgbDropdownConfig();

expect(config.up).toBe(false);
expect(config.autoClose).toBe(true);
});
});
12 changes: 12 additions & 0 deletions src/dropdown/dropdown-config.ts
@@ -0,0 +1,12 @@
import {Injectable, TemplateRef} from '@angular/core';

/**
* Configuration service for the NgbDropdown directive.
* You can inject this service, typically in your root component, and customize the values of its properties in
* order to provide default values for all the dropdowns used in the application.
*/
@Injectable()
export class NgbDropdownConfig {
up = false;
autoClose = true;
}
5 changes: 4 additions & 1 deletion src/dropdown/dropdown.module.ts
@@ -1,6 +1,9 @@
import {NgModule} from '@angular/core';
import {NGB_DROPDOWN_DIRECTIVES} from './dropdown';
import {NgbDropdownConfig} from './dropdown-config';

@NgModule({declarations: NGB_DROPDOWN_DIRECTIVES, exports: NGB_DROPDOWN_DIRECTIVES})
export {NgbDropdownConfig} from './dropdown-config';

@NgModule({declarations: NGB_DROPDOWN_DIRECTIVES, exports: NGB_DROPDOWN_DIRECTIVES, providers: [NgbDropdownConfig]})
export class NgbDropdownModule {
}
53 changes: 52 additions & 1 deletion src/dropdown/dropdown.spec.ts
@@ -1,11 +1,12 @@
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {TestBed, ComponentFixture, inject} from '@angular/core/testing';
import {createGenericTestComponent} from '../test/common';

import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';

import {NgbDropdownModule} from './dropdown.module';
import {NgbDropdown} from './dropdown';
import {NgbDropdownConfig} from './dropdown-config';

const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
Expand All @@ -17,6 +18,13 @@ function getDropdownEl(tc) {
describe('ngb-dropdown', () => {
beforeEach(() => { TestBed.configureTestingModule({declarations: [TestComponent], imports: [NgbDropdownModule]}); });

it('should initialize inputs with provided config', () => {
const defaultConfig = new NgbDropdownConfig();
const dropdown = new NgbDropdown(new NgbDropdownConfig);
expect(dropdown.up).toBe(defaultConfig.up);
expect(dropdown.autoClose).toBe(defaultConfig.autoClose);
});

it('should be closed and down by default', () => {
const html = `<div ngbDropdown></div>`;

Expand Down Expand Up @@ -268,6 +276,49 @@ describe('ngb-dropdown-toggle', () => {
fixture.detectChanges();
expect(dropdownEl).toHaveCssClass('open');
});


describe('Custom config', () => {
let config: NgbDropdownConfig;

beforeEach(() => {
TestBed.configureTestingModule({imports: [NgbDropdownModule]});
TestBed.overrideComponent(TestComponent, {set: {template: '<div ngbDropdown></div>'}});
});

beforeEach(inject([NgbDropdownConfig], (c: NgbDropdownConfig) => {
config = c;
config.up = true;
}));

it('should initialize inputs with provided config', () => {
const fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();

const compiled = fixture.nativeElement;

expect(getDropdownEl(compiled)).toHaveCssClass('dropup');
});
});

describe('Custom config as provider', () => {
let config = new NgbDropdownConfig();
config.up = true;

beforeEach(() => {
TestBed.configureTestingModule(
{imports: [NgbDropdownModule], providers: [{provide: NgbDropdownConfig, useValue: config}]});
});

it('should initialize inputs with provided config as provider', () => {
const fixture = createTestComponent('<div ngbDropdown></div>');
fixture.detectChanges();

const compiled = fixture.nativeElement;

expect(getDropdownEl(compiled)).toHaveCssClass('dropup');
});
});
});

@Component({selector: 'test-cmp', template: ''})
Expand Down
10 changes: 8 additions & 2 deletions src/dropdown/dropdown.ts
@@ -1,4 +1,5 @@
import {Directive, Input, Output, HostListener, EventEmitter} from '@angular/core';
import {NgbDropdownConfig} from './dropdown-config';

/**
* Transforms a node into a dropdown.
Expand All @@ -18,12 +19,12 @@ export class NgbDropdown {
/**
* Indicates that the dropdown should open upwards
*/
@Input() up = false;
@Input() up: boolean;

/**
* Indicates that dropdown should be closed when selecting one of dropdown items (click) or pressing ESC.
*/
@Input() autoClose = true;
@Input() autoClose: boolean;

/**
* Defines whether or not the dropdown-menu is open initially.
Expand All @@ -36,6 +37,11 @@ export class NgbDropdown {
*/
@Output() openChange = new EventEmitter();

constructor(config: NgbDropdownConfig) {
this.up = config.up;
this.autoClose = config.autoClose;
}


/**
* Checks if the dropdown menu is open or not.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -23,6 +23,7 @@ export {NgbTabChangeEvent} from './tabset/tabset.module';
export {NgbAlertConfig, NgbSelfClosingAlertConfig} from './alert/alert.module';
export {NgbCarouselConfig} from './carousel/carousel.module';
export {NgbDatepickerConfig} from './datepicker/datepicker.module';
export {NgbDropdownConfig} from './dropdown/dropdown.module';
export {NgbPaginationConfig} from './pagination/pagination.module';
export {NgbPopoverConfig} from './popover/popover.module';
export {NgbProgressbarConfig} from './progressbar/progressbar.module';
Expand Down

0 comments on commit e97d260

Please sign in to comment.