Home | History | Annotate | Download | only in paper-progress
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject 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 <!--
     17 Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html)
     18 
     19 The progress bars are for situations where the percentage completed can be
     20 determined. They give users a quick sense of how much longer an operation
     21 will take.
     22 
     23 Example:
     24 
     25     <paper-progress value="10"></paper-progress>
     26 
     27 There is also a secondary progress which is useful for displaying intermediate
     28 progress, such as the buffer level during a streaming playback progress bar.
     29 
     30 Example:
     31 
     32     <paper-progress value="10" secondary-progress="30"></paper-progress>
     33 
     34 ### Styling progress bar:
     35 
     36 To change the active progress bar color:
     37 
     38     paper-progress {
     39        --paper-progress-active-color: #e91e63;
     40     }
     41 
     42 To change the secondary progress bar color:
     43 
     44     paper-progress {
     45       --paper-progress-secondary-color: #f8bbd0;
     46     }
     47 
     48 To change the progress bar background color:
     49 
     50     paper-progress {
     51       --paper-progress-container-color: #64ffda;
     52     }
     53 
     54 Add the class `transiting` to a paper-progress to animate the progress bar when
     55 the 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 
     63 The following mixins are available for styling:
     64 
     65 Custom 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