• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!--
2@license
3Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7Code distributed by Google as part of the polymer project is also
8subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9-->
10
11<link rel="import" href="../polymer/polymer.html">
12<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
13<link rel="import" href="../iron-range-behavior/iron-range-behavior.html">
14<link rel="import" href="../paper-styles/color.html">
15
16<!--
17Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html)
18
19The progress bars are for situations where the percentage completed can be
20determined. They give users a quick sense of how much longer an operation
21will take.
22
23Example:
24
25    <paper-progress value="10"></paper-progress>
26
27There is also a secondary progress which is useful for displaying intermediate
28progress, such as the buffer level during a streaming playback progress bar.
29
30Example:
31
32    <paper-progress value="10" secondary-progress="30"></paper-progress>
33
34### Styling progress bar:
35
36To change the active progress bar color:
37
38    paper-progress {
39       --paper-progress-active-color: #e91e63;
40    }
41
42To change the secondary progress bar color:
43
44    paper-progress {
45      --paper-progress-secondary-color: #f8bbd0;
46    }
47
48To change the progress bar background color:
49
50    paper-progress {
51      --paper-progress-container-color: #64ffda;
52    }
53
54Add the class `transiting` to a paper-progress to animate the progress bar when
55the value changed. You can also customize the transition:
56
57    paper-progress {
58      --paper-progress-transition-duration: 0.08s;
59      --paper-progress-transition-timing-function: ease;
60      --paper-progress-transition-transition-delay: 0s;
61    }
62
63The following mixins are available for styling:
64
65Custom property                               | Description                                 | Default
66----------------------------------------------|---------------------------------------------|--------------
67`--paper-progress-container-color`            | Mixin applied to container                  | `--google-grey-300`
68`--paper-progress-transition-duration`        | Duration of the transition                  | `0.008s`
69`--paper-progress-transition-timing-function` | The timing function for the transition      | `ease`
70`--paper-progress-transition-delay`           | delay for the transition                    | `0s`
71`--paper-progress-active-color`               | The color of the active bar                 | `--google-green-500`
72`--paper-progress-secondary-color`            | The color of the secondary bar              | `--google-green-100`
73`--paper-progress-disabled-active-color`      | The color of the active bar if disabled     | `--google-grey-500`
74`--paper-progress-disabled-secondary-color`   | The color of the secondary bar if disabled  | `--google-grey-300`
75`--paper-progress-height`                     | The height of the progress bar              | `4px`
76
77@group Paper Elements
78@element paper-progress
79@hero hero.svg
80@demo demo/index.html
81-->
82
83<dom-module id="paper-progress">
84  <template>
85    <style>
86      :host {
87        display: block;
88        width: 200px;
89        position: relative;
90        overflow: hidden;
91      }
92
93      #progressContainer {
94        position: relative;
95      }
96
97      #progressContainer,
98      /* the stripe for the indeterminate animation*/
99      .indeterminate::after {
100        height: var(--paper-progress-height, 4px);
101      }
102
103      #primaryProgress,
104      #secondaryProgress,
105      .indeterminate::after {
106        @apply(--layout-fit);
107      }
108
109      #progressContainer,
110      .indeterminate::after {
111        background: var(--paper-progress-container-color, --google-grey-300);
112      }
113
114      :host(.transiting) #primaryProgress,
115      :host(.transiting) #secondaryProgress {
116        -webkit-transition-property: -webkit-transform;
117        transition-property: transform;
118
119        /* Duration */
120        -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s);
121        transition-duration: var(--paper-progress-transition-duration, 0.08s);
122
123        /* Timing function */
124        -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease);
125        transition-timing-function: var(--paper-progress-transition-timing-function, ease);
126
127        /* Delay */
128        -webkit-transition-delay: var(--paper-progress-transition-delay, 0s);
129        transition-delay: var(--paper-progress-transition-delay, 0s);
130      }
131
132      #primaryProgress,
133      #secondaryProgress {
134        @apply(--layout-fit);
135        -webkit-transform-origin: left center;
136        transform-origin: left center;
137        -webkit-transform: scaleX(0);
138        transform: scaleX(0);
139        will-change: transform;
140      }
141
142      #primaryProgress {
143        background: var(--paper-progress-active-color, --google-green-500);
144      }
145
146      #secondaryProgress {
147        background: var(--paper-progress-secondary-color, --google-green-100);
148      }
149
150      :host([disabled]) #primaryProgress {
151        background: var(--paper-progress-disabled-active-color, --google-grey-500);
152      }
153
154      :host([disabled]) #secondaryProgress {
155        background: var(--paper-progress-disabled-secondary-color, --google-grey-300);
156      }
157
158      :host(:not([disabled])) #primaryProgress.indeterminate {
159        -webkit-transform-origin: right center;
160        transform-origin: right center;
161        -webkit-animation: indeterminate-bar 2s linear infinite;
162        animation: indeterminate-bar 2s linear infinite;
163      }
164
165      :host(:not([disabled])) #primaryProgress.indeterminate::after {
166        content: "";
167        -webkit-transform-origin: center center;
168        transform-origin: center center;
169
170        -webkit-animation: indeterminate-splitter 2s linear infinite;
171        animation: indeterminate-splitter 2s linear infinite;
172      }
173
174      @-webkit-keyframes indeterminate-bar {
175        0% {
176          -webkit-transform: scaleX(1) translateX(-100%);
177        }
178        50% {
179          -webkit-transform: scaleX(1) translateX(0%);
180        }
181        75% {
182          -webkit-transform: scaleX(1) translateX(0%);
183          -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91);
184        }
185        100% {
186          -webkit-transform: scaleX(0) translateX(0%);
187        }
188      }
189
190      @-webkit-keyframes indeterminate-splitter {
191        0% {
192          -webkit-transform: scaleX(.75) translateX(-125%);
193        }
194        30% {
195          -webkit-transform: scaleX(.75) translateX(-125%);
196          -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8);
197        }
198        90% {
199          -webkit-transform: scaleX(.75) translateX(125%);
200        }
201        100% {
202          -webkit-transform: scaleX(.75) translateX(125%);
203        }
204      }
205
206      @keyframes indeterminate-bar {
207        0% {
208          transform: scaleX(1) translateX(-100%);
209        }
210        50% {
211          transform: scaleX(1) translateX(0%);
212        }
213        75% {
214          transform: scaleX(1) translateX(0%);
215          animation-timing-function: cubic-bezier(.28,.62,.37,.91);
216        }
217        100% {
218          transform: scaleX(0) translateX(0%);
219        }
220      }
221
222      @keyframes indeterminate-splitter {
223        0% {
224          transform: scaleX(.75) translateX(-125%);
225        }
226        30% {
227          transform: scaleX(.75) translateX(-125%);
228          animation-timing-function: cubic-bezier(.42,0,.6,.8);
229        }
230        90% {
231          transform: scaleX(.75) translateX(125%);
232        }
233        100% {
234          transform: scaleX(.75) translateX(125%);
235        }
236      }
237    </style>
238
239    <div id="progressContainer">
240      <div id="secondaryProgress" hidden$="[[_hideSecondaryProgress(secondaryRatio)]]"></div>
241      <div id="primaryProgress"></div>
242    </div>
243  </template>
244</dom-module>
245
246<script>
247  Polymer({
248    is: 'paper-progress',
249
250    behaviors: [
251      Polymer.IronRangeBehavior
252    ],
253
254    properties: {
255      /**
256       * The number that represents the current secondary progress.
257       */
258      secondaryProgress: {
259        type: Number,
260        value: 0
261      },
262
263      /**
264       * The secondary ratio
265       */
266      secondaryRatio: {
267        type: Number,
268        value: 0,
269        readOnly: true
270      },
271
272      /**
273       * Use an indeterminate progress indicator.
274       */
275      indeterminate: {
276        type: Boolean,
277        value: false,
278        observer: '_toggleIndeterminate'
279      },
280
281      /**
282       * True if the progress is disabled.
283       */
284      disabled: {
285        type: Boolean,
286        value: false,
287        reflectToAttribute: true,
288        observer: '_disabledChanged'
289      }
290    },
291
292    observers: [
293      '_progressChanged(secondaryProgress, value, min, max)'
294    ],
295
296    hostAttributes: {
297      role: 'progressbar'
298    },
299
300    _toggleIndeterminate: function(indeterminate) {
301      // If we use attribute/class binding, the animation sometimes doesn't translate properly
302      // on Safari 7.1. So instead, we toggle the class here in the update method.
303      this.toggleClass('indeterminate', indeterminate, this.$.primaryProgress);
304    },
305
306    _transformProgress: function(progress, ratio) {
307      var transform = 'scaleX(' + (ratio / 100) + ')';
308      progress.style.transform = progress.style.webkitTransform = transform;
309    },
310
311    _mainRatioChanged: function(ratio) {
312      this._transformProgress(this.$.primaryProgress, ratio);
313    },
314
315    _progressChanged: function(secondaryProgress, value, min, max) {
316      secondaryProgress = this._clampValue(secondaryProgress);
317      value = this._clampValue(value);
318
319      var secondaryRatio = this._calcRatio(secondaryProgress) * 100;
320      var mainRatio = this._calcRatio(value) * 100;
321
322      this._setSecondaryRatio(secondaryRatio);
323      this._transformProgress(this.$.secondaryProgress, secondaryRatio);
324      this._transformProgress(this.$.primaryProgress, mainRatio);
325
326      this.secondaryProgress = secondaryProgress;
327
328      this.setAttribute('aria-valuenow', value);
329      this.setAttribute('aria-valuemin', min);
330      this.setAttribute('aria-valuemax', max);
331    },
332
333    _disabledChanged: function(disabled) {
334      this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
335    },
336
337    _hideSecondaryProgress: function(secondaryRatio) {
338      return secondaryRatio === 0;
339    }
340  });
341</script>
342