Skip to content

Commit

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

Closes #671
  • Loading branch information
jnizet authored and pkozlowski-opensource committed Sep 3, 2016
1 parent 925a3cf commit 8b7047d
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>This rating uses customized default values.</p>

<ngb-rating [rate]="3"></ngb-rating>
15 changes: 15 additions & 0 deletions demo/src/app/components/rating/demos/config/config.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Component} from '@angular/core';
import {NgbRatingConfig} from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'ngbd-rating-config',
templateUrl: './config.component.html',
providers: [NgbRatingConfig] // add NgbRatingConfig to the component providers
})
export class RatingConfigComponent {
constructor(config: NgbRatingConfig) {
// customize default values of ratings used by this component tree
config.max = 5;
config.readonly = true;
}
}
7 changes: 6 additions & 1 deletion demo/src/app/components/rating/demos/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {RatingBasicComponent} from './basic/basic.component';
import {RatingConfigComponent} from './config/config.component';

export const DEMO_DIRECTIVES = [RatingBasicComponent];
export const DEMO_DIRECTIVES = [RatingBasicComponent, RatingConfigComponent];

export const DEMO_SNIPPETS = {
basic: {
code: require('!!prismjs?lang=typescript!./basic/basic.component'),
markup: require('!!prismjs?lang=markup!./basic/basic.component.html')
},
config: {
code: require('!!prismjs?lang=typescript!./config/config.component'),
markup: require('!!prismjs?lang=markup!./config/config.component.html')
}
};
6 changes: 6 additions & 0 deletions demo/src/app/components/rating/rating.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<ngbd-content-wrapper component="Rating">
<ngbd-api-docs directive="NgbRating"></ngbd-api-docs>
<ngbd-api-docs-config type="NgbRatingConfig"></ngbd-api-docs-config>
<ngbd-example-box demoTitle="Basic demo" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
<ngbd-rating-basic></ngbd-rating-basic>
</ngbd-example-box>
<ngbd-example-box demoTitle="Global configuration of ratings"
[htmlSnippet]="snippets.config.markup"
[tsSnippet]="snippets.config.code">
<ngbd-rating-config></ngbd-rating-config>
</ngbd-example-box>
</ngbd-content-wrapper>
2 changes: 1 addition & 1 deletion demo/src/app/components/rating/rating.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import { DEMO_SNIPPETS } from './demos';
import {DEMO_SNIPPETS} from './demos';

@Component({
selector: 'ngbd-rating',
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export {NgbAlertConfig, NgbDismissibleAlertConfig} from './alert/alert.module';
export {NgbCarouselConfig} from './carousel/carousel.module';
export {NgbPaginationConfig} from './pagination/pagination.module';
export {NgbProgressbarConfig} from './progressbar/progressbar.module';
export {NgbRatingConfig} from './rating/rating.module';

@NgModule({
exports: [
Expand Down
10 changes: 10 additions & 0 deletions src/rating/rating-config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {NgbRatingConfig} from './rating-config';

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

expect(config.max).toBe(10);
expect(config.readonly).toBe(false);
});
});
12 changes: 12 additions & 0 deletions src/rating/rating-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Injectable} from '@angular/core';

/**
* Configuration service for the NgbRating component.
* 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 ratings used in the application.
*/
@Injectable()
export class NgbRatingConfig {
max = 10;
readonly = false;
}
10 changes: 9 additions & 1 deletion src/rating/rating.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {NgbRatingConfig} from './rating-config';

import {NGB_RATING_DIRECTIVES} from './rating';

@NgModule({declarations: NGB_RATING_DIRECTIVES, exports: NGB_RATING_DIRECTIVES, imports: [CommonModule]})
export {NgbRatingConfig} from './rating-config';

@NgModule({
declarations: NGB_RATING_DIRECTIVES,
exports: NGB_RATING_DIRECTIVES,
imports: [CommonModule],
providers: [NgbRatingConfig]
})
export class NgbRatingModule {
}
55 changes: 52 additions & 3 deletions src/rating/rating.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {TestBed, ComponentFixture, inject} from '@angular/core/testing';
import {createGenericTestComponent} from '../util/tests';

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

import {NgbRatingModule} from './rating.module';
import {NgbRating} from './rating';
import {NgbRatingConfig} from './rating-config';

const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
Expand Down Expand Up @@ -38,14 +39,21 @@ function getState(compiled) {
describe('ngb-rating', () => {
beforeEach(() => { TestBed.configureTestingModule({declarations: [TestComponent], imports: [NgbRatingModule]}); });

it('should show 10 stars by default', () => {
it('should initialize inputs with default values', () => {
const defaultConfig = new NgbRatingConfig();
const rating = new NgbRating(new NgbRatingConfig());
expect(rating.max).toBe(defaultConfig.max);
expect(rating.readonly).toBe(defaultConfig.readonly);
});

it('should show as many stars as the configured max by default', () => {
const fixture = TestBed.createComponent(NgbRating);
fixture.detectChanges();

const compiled = fixture.nativeElement;

const stars = getStars(compiled);
expect(stars.length).toBe(10);
expect(stars.length).toBe(new NgbRatingConfig().max);
});

it('should change the num of stars with `max`', () => {
Expand Down Expand Up @@ -135,6 +143,47 @@ describe('ngb-rating', () => {
expect(compiled.querySelector('span').getAttribute('aria-valuenow')).toBe('7');
});
});

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

beforeEach(() => { TestBed.configureTestingModule({imports: [NgbRatingModule]}); });

beforeEach(inject([NgbRatingConfig], (c: NgbRatingConfig) => {
config = c;
config.max = 5;
config.readonly = true;
}));

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

let rating = fixture.componentInstance;
expect(rating.max).toBe(config.max);
expect(rating.readonly).toBe(config.readonly);
});
});

describe('Custom config as provider', () => {
let config = new NgbRatingConfig();
config.max = 5;
config.readonly = true;

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

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

let rating = fixture.componentInstance;
expect(rating.max).toBe(config.max);
expect(rating.readonly).toBe(config.readonly);
});
});
});

@Component({selector: 'test-cmp', template: ''})
Expand Down
10 changes: 8 additions & 2 deletions src/rating/rating.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Component, ChangeDetectionStrategy, Input, Output, EventEmitter, OnInit} from '@angular/core';
import {NgbRatingConfig} from './rating-config';

/**
* Rating directive that will take care of visualising a star rating bar.
Expand All @@ -24,7 +25,7 @@ export class NgbRating implements OnInit {
/**
* Maximal rating that can be given using this widget.
*/
@Input() max = 10;
@Input() max: number;

/**
* Current rating.
Expand All @@ -34,7 +35,7 @@ export class NgbRating implements OnInit {
/**
* A flag indicating if rating can be updated.
*/
@Input() readonly = false;
@Input() readonly: boolean;

/**
* An event fired when a user is hovering over a given rating.
Expand All @@ -54,6 +55,11 @@ export class NgbRating implements OnInit {
*/
@Output() rateChange = new EventEmitter<number>();

constructor(config: NgbRatingConfig) {
this.max = config.max;
this.readonly = config.readonly;
}

enter(value: number): void {
if (!this.readonly) {
this.rate = value;
Expand Down

0 comments on commit 8b7047d

Please sign in to comment.