fix(spinner): render properly and return mode defaults

closes ionic-team/stencil#90
This commit is contained in:
Brandy Carney
2017-08-16 12:38:03 -04:00
parent 94c8b0bf4a
commit 7b9782d3d0
2 changed files with 183 additions and 44 deletions

View File

@ -4,6 +4,99 @@ import { Config } from '../../index';
import { SPINNERS, SpinnerConfig } from './spinner-configs'; import { SPINNERS, SpinnerConfig } from './spinner-configs';
/**
* @name Spinner
* @description
* The `ion-spinner` component provides a variety of animated SVG spinners.
* Spinners enables you to give users feedback that the app is actively
* processing/thinking/waiting/chillin out, or whatever youd like it to indicate.
* By default, the `ion-refresher` feature uses this spinner component while it's
* the refresher is in the `refreshing` state.
*
* Ionic offers a handful of spinners out of the box, and by default, it will use
* the appropriate spinner for the platform on which its running.
*
* <table class="table spinner-table">
* <tr>
* <th>
* <code>lines</code>
* </th>
* <td>
* <ion-spinner name="lines"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th>
* <code>lines-small</code>
* </th>
* <td>
* <ion-spinner name="lines-small"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th>
* <code>bubbles</code>
* </th>
* <td>
* <ion-spinner name="bubbles"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th>
* <code>circles</code>
* </th>
* <td>
* <ion-spinner name="circles"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th>
* <code>crescent</code>
* </th>
* <td>
* <ion-spinner name="crescent"></ion-spinner>
* </td>
* </tr>
* <tr>
* <th>
* <code>dots</code>
* </th>
* <td>
* <ion-spinner name="dots"></ion-spinner>
* </td>
* </tr>
* </table>
*
* @usage
* The following code would use the default spinner for the platform it's
* running from. If it's neither iOS or Android, it'll default to use `ios`.
*
* ```html
* <ion-spinner></ion-spinner>
* ```
*
* By setting the `name` property, you can specify which predefined spinner to
* use, no matter what the platform is.
*
* ```html
* <ion-spinner name="bubbles"></ion-spinner>
* ```
*
* ## Styling SVG with CSS
* One cool thing about SVG is its ability to be styled with CSS! One thing to note
* is that some of the CSS properties on an SVG element have different names. For
* example, SVG uses the term `stroke` instead of `border`, and `fill` instead
* of `background-color`.
*
* ```css
* ion-spinner * {
* width: 28px;
* height: 28px;
* stroke: #444;
* fill: #222;
* }
* ```
*/
@Component({ @Component({
tag: 'ion-spinner', tag: 'ion-spinner',
styleUrls: { styleUrls: {
@ -20,39 +113,62 @@ export class Spinner {
color: string; color: string;
@Prop({ context: 'config' }) config: Config; @Prop({ context: 'config' }) config: Config;
@Prop() duration: number = null;
/**
* @input {string} How long it takes it to do one loop.
*/
@Prop() duration: number;
/**
* @input {string} SVG spinner name.
*/
@Prop() name: string; @Prop() name: string;
/**
* @input {boolean} If true, pause the animation.
*/
@Prop() paused: boolean = false; @Prop() paused: boolean = false;
ionViewDidLoad() { private getName(): string {
if (this.name === 'ios') { let name = this.name || this.config.get('spinner');
if (!name) {
// fallback
if (this.mode === 'md') {
return 'crescent';
} else if (this.mode === 'wp') {
return 'circles';
} else {
return 'lines';
}
}
if (name === 'ios') {
// deprecation warning, renamed in v4 // deprecation warning, renamed in v4
console.warn(`spinner "ios" has been renamed to "lines"`); console.warn(`spinner "ios" has been renamed to "lines"`);
name = 'lines';
} else if (this.name === 'ios-small') { } else if (name === 'ios-small') {
// deprecation warning, renamed in v4 // deprecation warning, renamed in v4
console.warn(`spinner "ios-small" has been renamed to "lines-sm"`); console.warn(`spinner "ios-small" has been renamed to "lines-sm"`);
name = 'lines-sm';
} }
return name;
} }
hostData() { hostData() {
const themedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.name}`); const themedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.getName()}`);
themedClasses['spinner-paused'] = true;
const spinnerClasses = {
...themedClasses,
'spinner-paused': this.paused
}
return { return {
class: themedClasses class: spinnerClasses
}; };
} }
render() { render() {
let name = this.name || this.config.get('spinner', 'lines'); const name = this.getName();
if (name === 'ios') {
name = this.name = 'lines';
} else if (this.name === 'ios-small') {
name = this.name = 'lines-sm';
}
const spinner = SPINNERS[name] || SPINNERS['lines']; const spinner = SPINNERS[name] || SPINNERS['lines'];
@ -83,19 +199,11 @@ function buildCircle(spinner: SpinnerConfig, duration: number, index: number, to
const data = spinner.fn(duration, index, total); const data = spinner.fn(duration, index, total);
data.style.animationDuration = duration + 'ms'; data.style.animationDuration = duration + 'ms';
return h('svg', { return (
attrs: { <svg viewBox='0 0 64 64' style={data.style}>
'viewBox': '0 0 64 64' <circle transform="translate(32,32)" r={data.r}></circle>
}, </svg>
style: data.style );
},
h('circle', {
attrs: {
'r': data.r,
'transform': 'translate(32,32)'
}
})
);
} }
@ -103,18 +211,9 @@ function buildLine(spinner: SpinnerConfig, duration: number, index: number, tota
const data = spinner.fn(duration, index, total); const data = spinner.fn(duration, index, total);
data.style.animationDuration = duration + 'ms'; data.style.animationDuration = duration + 'ms';
return h('svg', { return (
attrs: { <svg viewBox='0 0 64 64' style={data.style}>
'viewBox': '0 0 64 64' <line transform="translate(32,32)" y1={data.y1} y2={data.y2}></line>
}, </svg>
style: data.style );
},
h('line', {
attrs: {
'y1': data.y1,
'y2': data.y2,
'transform': 'translate(32,32)'
}
})
);
} }

View File

@ -2,11 +2,51 @@
<html dir="ltr"> <html dir="ltr">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Ionic Buttons</title> <title>Ionic Spinners</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="/dist/ionic.js"></script> <script src="/dist/ionic.js"></script>
</head> </head>
<body> <body>
<ion-spinner name="bubbles"></ion-spinner> <ion-app>
<ion-content>
<ion-list>
<ion-list-header>
Spinner Loading Indicators
</ion-list-header>
<ion-item>
<ion-spinner slot="start"></ion-spinner>
Show Default Spinner
</ion-item>
<ion-item>
<ion-spinner slot="start" name="lines"></ion-spinner>
Show Lines
</ion-item>
<ion-item>
<ion-spinner slot="start" name="ios-small"></ion-spinner>
Show Lines Small
</ion-item>
<ion-item>
<ion-spinner slot="start" name="dots"></ion-spinner>
Show Dots
</ion-item>
<ion-item>
<ion-spinner slot="start" name="bubbles"></ion-spinner>
Show Bubbles
</ion-item>
<ion-item>
<ion-spinner slot="start" name="circles"></ion-spinner>
Show Circles
</ion-item>
<ion-item>
<ion-spinner slot="start" name="crescent"></ion-spinner>
Show Crescent
</ion-item>
<ion-item>
<ion-spinner slot="start" paused></ion-spinner>
Show Paused Default Spinner
</ion-item>
</ion-list>
</ion-content>
</ion-app>
</body> </body>
</html> </html>