Skip to content

Commit

Permalink
fix: change clrSpinner API
Browse files Browse the repository at this point in the history
Signed-off-by: Bozhidar Dryanovski <bozhidar.dryanovski@gmail.com>
  • Loading branch information
bdryanovski committed Jul 23, 2019
1 parent c58007e commit 256df22
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 66 deletions.
14 changes: 9 additions & 5 deletions golden/clr-angular.d.ts
Expand Up @@ -1031,13 +1031,17 @@ export declare class ClrSignpostTrigger implements OnDestroy {

export declare class ClrSpinner {
assertive: boolean;
readonly assignClass: string;
inline: boolean;
inverse: boolean;
medium: boolean;
clrInline: boolean | string;
clrInverse: boolean | string;
clrMedium: boolean | string;
clrSmall: boolean | string;
readonly inlineClass: boolean;
readonly inverseClass: boolean;
readonly mediumClass: boolean;
off: boolean;
readonly setAriaLive: "assertive" | "off" | "polite";
small: boolean;
readonly smallClass: boolean;
readonly spinnerClass: boolean;
}

export declare class ClrSpinnerModule {
Expand Down
2 changes: 1 addition & 1 deletion src/clr-angular/data/datagrid/datagrid-row.html
Expand Up @@ -59,7 +59,7 @@
[attr.dir]="expand.expanded ? 'down' : 'right'"
[attr.title]="expand.expanded ? commonStrings.collapse : commonStrings.expand"></clr-icon>
</button>
<clr-spinner *ngIf="expand.loading" small>{{ commonStrings.loading }}</clr-spinner>
<clr-spinner *ngIf="expand.loading" clrSmall>{{ commonStrings.loading }}</clr-spinner>
</ng-container>
</div>
<ng-container #scrollableCells></ng-container>
Expand Down
2 changes: 1 addition & 1 deletion src/clr-angular/data/datagrid/datagrid.html
Expand Up @@ -53,7 +53,7 @@
</div>
<ng-content select="clr-dg-footer"></ng-content>
<div class="datagrid-spinner" *ngIf="loading">
<clr-spinner medium>Loading</clr-spinner>
<clr-spinner clrMedium>Loading</clr-spinner>
</div>

<div class="datagrid-calculation-table">
Expand Down
47 changes: 43 additions & 4 deletions src/clr-angular/progress/spinner/spinner.spec.ts
Expand Up @@ -17,30 +17,36 @@ const SPINNER_INLINE = 'spinner-inline';

const SPINNER_SMALL_SIZE = 'spinner-sm';
const SPINNER_MEDIUM_SIZE = 'spinner-md';
const SPINNER_LARGE_SIZE = 'spinner-lg';

@Component({
template: `<clr-spinner small medium inline>Loading ...</clr-spinner>`,
template: `<clr-spinner clrSmall clrMedium clrInline>Loading ...</clr-spinner>`,
})
class TestComponent {}

@Component({
template: `<clr-spinner small inverse off>Loading ...</clr-spinner>`,
template: `<clr-spinner clrSmall clrInverse clrOff>Loading ...</clr-spinner>`,
})
class TestSmallComponent {}

@Component({
template: `<clr-spinner medium assertive>Loading ...</clr-spinner>`,
template: `<clr-spinner clrMedium clrAssertive>Loading ...</clr-spinner>`,
})
class TestMediumComponent {}

@Component({
template: `<clr-spinner>Loading ...</clr-spinner>`,
})
class TestLargeComponent {}

describe('ClrSpinner component', () => {
describe('View', () => {
let fixture: ComponentFixture<any>;
let clrSpinner;

beforeEach(function() {
TestBed.configureTestingModule({
declarations: [TestComponent, TestSmallComponent, TestMediumComponent],
declarations: [TestComponent, TestSmallComponent, TestMediumComponent, TestLargeComponent],
imports: [ClrSpinnerModule],
});
});
Expand Down Expand Up @@ -95,6 +101,39 @@ describe('ClrSpinner component', () => {
});

describe('Sizes', () => {
function componentWidth(fix): number {
return Math.floor(fix.debugElement.query(By.directive(ClrSpinner)).nativeElement.getBoundingClientRect().width);
}

function componentHeight(fix): number {
return Math.floor(
fix.debugElement.query(By.directive(ClrSpinner)).nativeElement.getBoundingClientRect().height
);
}
it(`.${SPINNER_SMALL_SIZE} should have the size ot 18x18`, () => {
const fixtureSmall = TestBed.createComponent(TestSmallComponent);
fixtureSmall.detectChanges();

expect(componentHeight(fixtureSmall)).toBe(18);
expect(componentWidth(fixtureSmall)).toBe(18);
});

it(`.${SPINNER_MEDIUM_SIZE} should have the size ot 36x36`, () => {
const fixtureMedium = TestBed.createComponent(TestMediumComponent);
fixtureMedium.detectChanges();

expect(componentHeight(fixtureMedium)).toBe(36);
expect(componentWidth(fixtureMedium)).toBe(36);
});

it(`.${SPINNER_LARGE_SIZE} should have the size ot 72x72`, () => {
const fixtureLarge = TestBed.createComponent(TestLargeComponent);
fixtureLarge.detectChanges();

expect(componentHeight(fixtureLarge)).toBe(72);
expect(componentWidth(fixtureLarge)).toBe(72);
});

it(`should add .${SPINNER_SMALL_SIZE}`, () => {
fixture = TestBed.createComponent(TestSmallComponent);
clrSpinner = fixture.debugElement.query(By.directive(ClrSpinner)).nativeElement;
Expand Down
128 changes: 89 additions & 39 deletions src/clr-angular/progress/spinner/spinner.ts
Expand Up @@ -3,42 +3,113 @@
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component, Input } from '@angular/core';
import { Component, Input, HostBinding } from '@angular/core';
import { isBooleanAttributeSet } from '../../utils/component/is-boolean-attribute-set';

const SPINNER_BASE_CLASS = 'spinner';

const SPINNER_INVERSE = 'spinner-inverse';
const SPINNER_INLINE = 'spinner-inline';

const SPINNER_SMALL_SIZE = 'spinner-sm';
const SPINNER_MEDIUM_SIZE = 'spinner-md';

@Component({
selector: 'clr-spinner',
template: `
<ng-content></ng-content>
`,
host: {
'[attr.class]': 'assignClass',
'[attr.aria-live]': 'setAriaLive',
'[attr.aria-busy]': 'true',
},
})
export class ClrSpinner {
/**
* Default class for all spinners. This class is always true
*/
@HostBinding('class.spinner')
get spinnerClass() {
return true;
}

// Style
@Input() inline: boolean;
@Input() inverse: boolean;
private _inline: boolean;
@HostBinding('class.spinner-inline')
get inlineClass() {
return this._inline;
}

@Input('clrInline')
set clrInline(value: boolean | string) {
this._inline = isBooleanAttributeSet(value);
}

private _inverse: boolean;
@HostBinding('class.spinner-inverse')
get inverseClass() {
return this._inverse;
}

@Input('clrInverse')
set clrInverse(value: boolean | string) {
this._inverse = isBooleanAttributeSet(value);
}

// Size
@Input() small: boolean;
@Input() medium: boolean;
/* No need to handle large - default value */
/**
* By default all spinners are Large. (spinner-lg)
* To change the size you need to use set clrSmall or clrMedium to TRUE/
*/

/**
* Small
*/
private _small: boolean;
@HostBinding('class.spinner-sm')
get smallClass() {
return this._small;
}

@Input('clrSmall')
set clrSmall(value: boolean | string) {
this._small = isBooleanAttributeSet(value);
}

/**
* When clrSmall & clrMedium are set both to true.
* The CSS with high priority will be small - so medium size will be ignored.
*
* For this reason if clrSmall is set we won't add clrMedium class.
*
* NOTE: This is dictated by the CSS rules.
* DON'T USE clrSmall & clrMedium to toggle classes. This could change without notice.
*
* Also there is no logical need to have both of them set to TRUE or FALSE.
*/
private _medium: boolean;
@HostBinding('class.spinner-md')
get mediumClass() {
if (this._small) {
return false;
}
return this._medium;
}

@Input('clrMedium')
set clrMedium(value: boolean | string) {
this._medium = isBooleanAttributeSet(value);
}

// Aria Live
@Input() assertive: boolean;
@Input() off: boolean;
/* No need to handle polite - default value */

/**
* By default aria-live will be set to `polite` .
* To change is it you need to set clrAssertive or clrOff to TRUE
*
* There is priority:
* Default: polite
* Asertive
* Off
*
* In case when for some reason you have clrAssertive=TRUE and clrOff=TRUE,
* we gonna set `assertive` as value of aria-live.
*
*/
@Input('clrAssertive') assertive: boolean;
@Input('clrOff') off: boolean;

get setAriaLive() {
if (isBooleanAttributeSet(this.assertive)) {
Expand All @@ -49,25 +120,4 @@ export class ClrSpinner {
}
return 'polite';
}

get assignClass(): string {
const classes = [SPINNER_BASE_CLASS];

if (isBooleanAttributeSet(this.inline)) {
classes.push(SPINNER_INLINE);
}

if (isBooleanAttributeSet(this.inverse)) {
classes.push(SPINNER_INVERSE);
}

// You could have only on size at a time...
if (isBooleanAttributeSet(this.small)) {
classes.push(SPINNER_SMALL_SIZE);
} else if (isBooleanAttributeSet(this.medium)) {
classes.push(SPINNER_MEDIUM_SIZE);
}

return classes.join(' ');
}
}
21 changes: 21 additions & 0 deletions src/dev/src/app/spinners/spinner-component.html
@@ -0,0 +1,21 @@
<!--
~ Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
~ This software is released under MIT license.
~ The full license information can be found in LICENSE in the root directory of this project.
-->

<h5>Small</h5>
<div class="clr-example squeeze">
<clr-spinner clrSmall>Fetching data</clr-spinner>
</div>

<h5>Medium</h5>
<div class="clr-example squeeze">
<clr-spinner clrMedium clrAssertive>Loading users</clr-spinner>

</div>

<h5>Large (default)</h5>
<div class="clr-example squeeze">
<clr-spinner clrOff>You won't hear about me</clr-spinner>
</div>
12 changes: 12 additions & 0 deletions src/dev/src/app/spinners/spinner-component.ts
@@ -0,0 +1,12 @@
/*
* Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component } from '@angular/core';

@Component({
selector: 'clr-spinner-component',
templateUrl: './spinner-component.html',
})
export class SpinnerComponentDemo {}
4 changes: 3 additions & 1 deletion src/dev/src/app/spinners/spinner.demo.ts
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
Expand All @@ -13,6 +13,8 @@ import { Component } from '@angular/core';
<ul>
<li><a [routerLink]="['./spinner-types']">Types of spinners</a></li>
<li><a [routerLink]="['./spinner-sizes']">Spinner sizes</a></li>
<li><a [routerLink]="['./spinner-component']">Spinner component</a></li>
</ul>
<router-outlet></router-outlet>
`,
Expand Down
7 changes: 4 additions & 3 deletions src/dev/src/app/spinners/spinners.demo.module.ts
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
Expand All @@ -10,12 +10,13 @@ import { ClarityModule } from '@clr/angular';

import { SpinnerSizesDemo } from './spinner-sizes';
import { SpinnerTypesDemo } from './spinner-types';
import { SpinnerComponentDemo } from './spinner-component';
import { SpinnerDemo } from './spinner.demo';
import { ROUTING } from './spinners.demo.routing';

@NgModule({
imports: [CommonModule, ClarityModule, ROUTING],
declarations: [SpinnerDemo, SpinnerSizesDemo, SpinnerTypesDemo],
exports: [SpinnerDemo, SpinnerSizesDemo, SpinnerTypesDemo],
declarations: [SpinnerDemo, SpinnerSizesDemo, SpinnerTypesDemo, SpinnerComponentDemo],
exports: [SpinnerDemo, SpinnerSizesDemo, SpinnerTypesDemo, SpinnerComponentDemo],
})
export class SpinnersDemoModule {}
4 changes: 3 additions & 1 deletion src/dev/src/app/spinners/spinners.demo.routing.ts
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
* Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
Expand All @@ -9,6 +9,7 @@ import { RouterModule, Routes } from '@angular/router';
import { SpinnerSizesDemo } from './spinner-sizes';
import { SpinnerTypesDemo } from './spinner-types';
import { SpinnerDemo } from './spinner.demo';
import { SpinnerComponentDemo } from './spinner-component';

const ROUTES: Routes = [
{
Expand All @@ -18,6 +19,7 @@ const ROUTES: Routes = [
{ path: '', redirectTo: 'spinner-types', pathMatch: 'full' },
{ path: 'spinner-types', component: SpinnerTypesDemo },
{ path: 'spinner-sizes', component: SpinnerSizesDemo },
{ path: 'spinner-component', component: SpinnerComponentDemo },
],
},
];
Expand Down
Expand Up @@ -58,7 +58,7 @@ <h5>Modify</h5>
</button>

<div *ngIf="downloadingFile">
<clr-spinner inline>Downloading</clr-spinner>
<clr-spinner clrInline>Downloading</clr-spinner>
<span> Downloading</span>
</div>
</div>
Expand All @@ -78,6 +78,6 @@ <h5>Accessibility live region</h5>
<button *ngIf="!downloadinInvoice" (click)="toggleProgressBar('downloadinInvoice')" class="btn btn-primary">
Download Invoice
</button>
<clr-spinner *ngIf="downloadinInvoice" medium assertive>Downloading</clr-spinner>
<clr-spinner *ngIf="downloadinInvoice" clrMedium clrAssertive>Downloading</clr-spinner>
</div>
<clr-code-snippet [clrCode]="example2"></clr-code-snippet>

0 comments on commit 256df22

Please sign in to comment.