1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | import onsElements from '../ons/elements.js';
|
15 | import util from '../ons/util.js';
|
16 | import BaseInputElement from './base/base-input.js';
|
17 |
|
18 | const scheme = {
|
19 | '': 'range--*',
|
20 | '.range__input': 'range--*__input',
|
21 | '.range__focus-ring': 'range--*__focus-ring'
|
22 | };
|
23 |
|
24 | const activeClassToken = 'range__input--active';
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | export default class RangeElement extends BaseInputElement {
|
51 |
|
52 | constructor() {
|
53 | super();
|
54 |
|
55 | this._onMouseDown = this._onMouseDown.bind(this);
|
56 | this._onMouseUp = this._onMouseUp.bind(this);
|
57 | this._onTouchStart = this._onTouchStart.bind(this);
|
58 | this._onTouchEnd = this._onTouchEnd.bind(this);
|
59 | this._onInput = this._update.bind(this);
|
60 | this._onDragstart = this._onDragstart.bind(this);
|
61 | this._onDragend = this._onDragend.bind(this);
|
62 | }
|
63 |
|
64 | _compile() {
|
65 | super._compile();
|
66 | this._updateDisabled(this.hasAttribute('disabled'));
|
67 | }
|
68 |
|
69 |
|
70 |
|
71 | _update() {
|
72 | const input = this._input;
|
73 | const focusRing = this._focusRing;
|
74 |
|
75 | input.style.backgroundSize = `${100 * this._ratio}% 2px`;
|
76 | focusRing.value = this.value;
|
77 |
|
78 |
|
79 | if ((input.min === '' && input.value === '0') || input.min === input.value) {
|
80 | input.setAttribute('_zero', '');
|
81 | } else {
|
82 | input.removeAttribute('_zero');
|
83 | }
|
84 |
|
85 | ['min', 'max'].forEach(attr => focusRing[attr] = input[attr]);
|
86 | }
|
87 |
|
88 | get _scheme() {
|
89 | return scheme;
|
90 | }
|
91 |
|
92 | get _template() {
|
93 | return `
|
94 | <input type="${this.type}" class="${this._defaultClassName}__input">
|
95 | <input type="range" class="range__focus-ring" tabIndex="-1">
|
96 | `;
|
97 | }
|
98 |
|
99 | get _defaultClassName() {
|
100 | return 'range';
|
101 | }
|
102 |
|
103 | get type() {
|
104 | return 'range';
|
105 | }
|
106 |
|
107 |
|
108 |
|
109 | _onMouseDown(e) {
|
110 | this._input.classList.add(activeClassToken);
|
111 | setImmediate(() => this._input.focus());
|
112 | }
|
113 |
|
114 | _onTouchStart(e) {
|
115 | this._onMouseDown();
|
116 | }
|
117 |
|
118 | _onMouseUp(e) {
|
119 | this._input.classList.remove(activeClassToken);
|
120 | }
|
121 |
|
122 | _onTouchEnd(e) {
|
123 | this._onMouseUp(e);
|
124 | }
|
125 |
|
126 | _onDragstart(e) {
|
127 | e.consumed = true;
|
128 | e.gesture.stopPropagation();
|
129 | this._input.classList.add(activeClassToken);
|
130 | this.addEventListener('drag', this._onDrag);
|
131 | }
|
132 |
|
133 | _onDrag(e) {
|
134 | e.stopPropagation();
|
135 | }
|
136 |
|
137 | _onDragend(e) {
|
138 | this._input.classList.remove(activeClassToken);
|
139 | this.removeEventListener('drag', this._onDrag);
|
140 | }
|
141 |
|
142 | get _focusRing() {
|
143 | return this.children[1];
|
144 | }
|
145 |
|
146 | get _ratio() {
|
147 |
|
148 | const min = this._input.min === '' ? 0 : parseInt(this._input.min);
|
149 | const max = this._input.max === '' ? 100 : parseInt(this._input.max);
|
150 |
|
151 | return (this.value - min) / (max - min);
|
152 | }
|
153 |
|
154 | static get observedAttributes() {
|
155 | return ['disabled', ...BaseInputElement.observedAttributes];
|
156 | }
|
157 |
|
158 | attributeChangedCallback(name, last, current) {
|
159 | if (name === 'disabled') {
|
160 | this._updateDisabled(current);
|
161 | }
|
162 | super.attributeChangedCallback(name, last, current);
|
163 | }
|
164 |
|
165 | |
166 |
|
167 |
|
168 | _updateDisabled(disabled) {
|
169 | if (disabled) {
|
170 | this.classList.add('range--disabled');
|
171 | } else {
|
172 | this.classList.remove('range--disabled');
|
173 | }
|
174 | }
|
175 |
|
176 | connectedCallback() {
|
177 | this._setupListeners(true);
|
178 | }
|
179 |
|
180 | disconnectedCallback() {
|
181 | this._setupListeners(false);
|
182 | }
|
183 |
|
184 | _setupListeners(add) {
|
185 | const action = (add ? 'add' : 'remove') + 'EventListener';
|
186 | util[action](this, 'touchstart', this._onTouchStart, { passive: true });
|
187 | this[action]('mousedown', this._onMouseDown);
|
188 | this[action]('mouseup', this._onMouseUp);
|
189 | this[action]('touchend', this._onTouchEnd);
|
190 | this[action]('dragstart', this._onDragstart);
|
191 | this[action]('dragend', this._onDragend);
|
192 | this[action]('input', this._onInput);
|
193 | }
|
194 |
|
195 | |
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 | |
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 | |
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 | |
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 | }
|
234 |
|
235 | onsElements.Range = RangeElement;
|
236 | customElements.define('ons-range', RangeElement);
|