UNPKG

@kano/web-components

Version:

Shared web-components for the Kano ecosystem.

196 lines (181 loc) 6.16 kB
/** `kano-progress-bar` The following custom properties and mixins are also available for styling: Custom property | Description | Default ----------------|-------------|---------- `--kano-progress-bar-main` | Custom property applied to host| `{}`, `--kano-progress-bar-bg-color` | Custom property applied to the progress bar background color | `{}`, `--kano-progress-bar-color` | Custom property to the progress bar fill color | `{}` `--kano-progress-bar-label` | Mixin applied to the progress label | `{}` @group Kano Elements @demo ./kano-progress-bar/demo/kano-progress-bar.html */ /* FIXME(polymer-modulizer): the above comments were extracted from HTML and may be out of place here. Review them and then delete this comment! */ import '@polymer/polymer/polymer-legacy.js'; import '../kano-style/typography.js'; import '../kano-style/color.js'; import { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js'; import { html } from '@polymer/polymer/lib/utils/html-tag.js'; Polymer({ _template: html` <style> :host { display: block; width: 100%; height: 12px; @apply --kano-progress-bar-main; } :host .slider-container { height: 100%; position: relative; } :host .label-container { position: absolute; top: -40px; left: 0px; width: 100%; transform: translateX(-100%); font-family: var(--font-body, sans-serif); @apply --kano-progress-bar-label; } :host .label { float: right; } :host #progress-fill { width: 100%; height: 100%; background: var(--kano-progress-bar-color, var(--color-light-green)); border-radius: 12px; transform: translateX(-100%); } :host .progress-shadow { position: relative; width: 100%; height: 100%; backface-visibility: hidden; z-index: 2; overflow: hidden; border-radius: 12px; background: var(--kano-progress-bar-bg-color, var(--color-grey-lightest)); } </style> <div id="progress" class="slider-container"> <div class="progress-shadow"> <div id="progress-fill"></div> </div> <div hidden\$="[[!displayLabel]]" id="progress-label" class="label-container"> <div class="label"> <slot name="label"></slot> </div> </div> </div> `, is: 'kano-progress-bar', properties: { /** * The minimum value in the progress bar's range */ min: { type: Number, value: 0, }, /** * The maximum value in the progress bar's range */ max: { type: Number, value: 100 }, /** * The static value of the bar before any incrementing */ startValue: { type: Number, value: 0, observer: 'setupBar' }, /** * The up-to-date value of the progress bar */ immediateValue: { type: Number, value: null, notify: true }, animating: { type: Boolean, value: false }, displayLabel: { type: Boolean, value: false } }, observers: [ 'setupBar(startValue, min, max)' ], setupBar (value, min, max) { var startRatio = (value - this.min) / (this.max - this.min); this.immediateValue = this.startValue; this.$['progress-fill'].style.transform = `translateX(-${100 - startRatio * 100}%)`; if (this.displayLabel) { this.$['progress-label'].style.transform = `translateX(-${100 - startRatio * 100}%)`; } this._checkLimits(value); }, addValue (addedValue, speed) { if (this.inProgress || !addedValue) { return; } speed = speed || 700; this.$['progress-fill'].style.transition = `transform ${speed}ms linear`; this.$['progress-label'].style.transition = `transform ${speed}ms linear`; this._animateProgress(addedValue + this.startValue, this.startValue, speed); }, _animateProgress (targetValue, oldValue, speed) { var newRatio = (targetValue - this.min) / (this.max - this.min); newRatio = this._limitingValue(newRatio, 0, 1); this.inProgress = true; this.$['progress-fill'].style.transform = `translateX(-${100 - newRatio * 100}%)`; if (this.displayLabel) { this.$['progress-label'].style.transform = `translateX(-${100 - newRatio * 100}%)`; } this._incrementValue(targetValue, oldValue, speed / Math.abs(targetValue - oldValue)); }, _incrementValue (targetValue, oldValue, frequency) { if (this.min <= targetValue && this.max >= targetValue) { // incrementing or decrementing var incrementUnit = targetValue > oldValue ? +1 : -1, incrementing = setInterval(() => { this.immediateValue = this.immediateValue + incrementUnit; if (this.immediateValue >= targetValue) { this.startValue = this.immediateValue; this.inProgress = false; clearInterval(incrementing); } }, frequency); } else { this.inProgress = false; } }, _checkLimits (value) { if (value <= this.min) { this.fire('min-reached'); } else if (value >= this.max) { this.fire('max-reached'); } }, _limitingValue (value, min, max) { value = Math.min(value, max); value = Math.max(value, min); return value; }, _resetTransition () { this.$['progress-fill'].style.transition = 'none'; this.$['progress-label'].style.transition = 'none'; } });