UNPKG

6.88 kBJavaScriptView Raw
1/*
2Copyright 2013-2015 ASIAL CORPORATION
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15
16*/
17
18import onsElements from '../ons/elements.js';
19import util from '../ons/util.js';
20import autoStyle from '../ons/autostyle.js';
21import ModifierUtil from '../ons/internal/modifier-util.js';
22import BaseElement from './base/base-element.js';
23import contentReady from '../ons/content-ready.js';
24
25const scheme = {
26 '.progress-bar': 'progress-bar--*',
27 '.progress-bar__primary': 'progress-bar--*__primary',
28 '.progress-bar__secondary': 'progress-bar--*__secondary'
29};
30
31const template = util.createElement(`
32 <div class="progress-bar">
33 <div class="progress-bar__secondary"></div>
34 <div class="progress-bar__primary"></div>
35 </div>
36`);
37
38const INDET = 'indeterminate';
39
40/**
41 * @element ons-progress-bar
42 * @category visual
43 * @modifier material
44 * [en]Display a Material Design progress bar.[/en]
45 * [ja]マテリアルデザインのスタイルでプログレスバーを表示します。[/ja]
46 * @description
47 * [en]
48 * The component is used to display a linear progress bar. It can either display a progress bar that shows the user how much of a task has been completed. In the case where the percentage is not known it can be used to display an animated progress bar so the user can see that an operation is in progress.
49 * [/en]
50 * [ja][/ja]
51 * @codepen zvQbGj
52 * @tutorial vanilla/Reference/progress
53 * @seealso ons-progress-circular
54 * [en]The `<ons-progress-circular>` component displays a circular progress indicator.[/en]
55 * [ja][/ja]
56 * @example
57 * <ons-progress-bar
58 * value="55"
59 * secondary-value="87">
60 * </ons-progress-bar>
61 *
62 * <ons-progress-bar
63 * indeterminate>
64 * </ons-progress-bar>
65 */
66export default class ProgressBarElement extends BaseElement {
67
68 /**
69 * @attribute modifier
70 * @type {String}
71 * @description
72 * [en]Change the appearance of the progress indicator.[/en]
73 * [ja]プログレスインジケータの見た目を変更します。[/ja]
74 */
75
76 /**
77 * @attribute value
78 * @type {Number}
79 * @description
80 * [en]Current progress. Should be a value between 0 and 100.[/en]
81 * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
82 */
83
84 /**
85 * @attribute secondary-value
86 * @type {Number}
87 * @description
88 * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
89 * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
90 */
91
92 /**
93 * @attribute indeterminate
94 * @description
95 * [en]If this attribute is set, an infinite looping animation will be shown.[/en]
96 * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
97 */
98
99 constructor() {
100 super();
101
102 contentReady(this, () => this._compile());
103 }
104
105 _compile() {
106 if (!this._isCompiled()) {
107 this._template = template.cloneNode(true);
108 } else {
109 this._template = util.findChild(this, '.progress-bar');
110 }
111
112 this._primary = util.findChild(this._template, '.progress-bar__primary');
113 this._secondary = util.findChild(this._template, '.progress-bar__secondary');
114
115 this._updateDeterminate();
116 this._updateValue();
117
118 this.appendChild(this._template);
119
120 autoStyle.prepare(this);
121 ModifierUtil.initModifier(this, scheme);
122 }
123
124 _isCompiled() {
125 if (!util.findChild(this, '.progress-bar')) {
126 return false;
127 }
128
129 const barElement = util.findChild(this, '.progress-bar');
130
131 if (!util.findChild(barElement, '.progress-bar__secondary')) {
132 return false;
133 }
134
135 if (!util.findChild(barElement, '.progress-bar__primary')) {
136 return false;
137 }
138
139 return true;
140 }
141
142 static get observedAttributes() {
143 return ['modifier', 'value', 'secondary-value', INDET];
144 }
145
146 attributeChangedCallback(name, last, current) {
147 if (name === 'modifier') {
148 ModifierUtil.onModifierChanged(last, current, this, scheme);
149 this.hasAttribute(INDET) && this._updateDeterminate();
150 } else if (name === 'value' || name === 'secondary-value') {
151 this._updateValue();
152 } else if (name === INDET) {
153 this._updateDeterminate();
154 }
155 }
156
157 _updateDeterminate() {
158 contentReady(this, () => util.toggleModifier(this, INDET, { force: this.hasAttribute(INDET) }));
159 }
160
161 _updateValue() {
162 contentReady(this, () => {
163 this._primary.style.width = (this.hasAttribute('value')) ? this.getAttribute('value') + '%' : '0%';
164 this._secondary.style.width = this.hasAttribute('secondary-value') ? this.getAttribute('secondary-value') + '%' : '0%';
165 });
166 }
167
168 /**
169 * @property value
170 * @type {Number}
171 * @description
172 * [en]Current progress. Should be a value between 0 and 100.[/en]
173 * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
174 */
175 set value(value) {
176 if (typeof value !== 'number' || value < 0 || value > 100) {
177 util.throw('Invalid value');
178 }
179
180 this.setAttribute('value', Math.floor(value));
181 }
182
183 get value() {
184 return parseInt(this.getAttribute('value') || '0');
185 }
186
187 /**
188 * @property secondaryValue
189 * @type {Number}
190 * @description
191 * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
192 * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
193 */
194 set secondaryValue(value) {
195 if (typeof value !== 'number' || value < 0 || value > 100) {
196 util.throw('Invalid value');
197 }
198
199 this.setAttribute('secondary-value', Math.floor(value));
200 }
201
202 get secondaryValue() {
203 return parseInt(this.getAttribute('secondary-value') || '0');
204 }
205
206 /**
207 * @property indeterminate
208 * @type {Boolean}
209 * @description
210 * [en]If this property is `true`, an infinite looping animation will be shown.[/en]
211 * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
212 */
213 set indeterminate(value) {
214 if (value) {
215 this.setAttribute(INDET, '');
216 }
217 else {
218 this.removeAttribute(INDET);
219 }
220 }
221
222 get indeterminate() {
223 return this.hasAttribute(INDET);
224 }
225}
226
227onsElements.ProgressBar = ProgressBarElement;
228customElements.define('ons-progress-bar', ProgressBarElement);