@materializecss/materialize 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/Gruntfile.js +712 -708
  2. package/LICENSE +0 -0
  3. package/README.md +1 -7
  4. package/dist/css/materialize.css +8671 -8627
  5. package/dist/css/materialize.min.css +3 -3
  6. package/dist/js/materialize.js +11706 -11559
  7. package/dist/js/materialize.min.js +2 -2
  8. package/extras/noUiSlider/nouislider.css +2 -4
  9. package/extras/noUiSlider/nouislider.js +0 -0
  10. package/extras/noUiSlider/nouislider.min.js +0 -0
  11. package/js/anime.min.js +0 -0
  12. package/js/autocomplete.js +0 -0
  13. package/js/buttons.js +0 -0
  14. package/js/cards.js +0 -0
  15. package/js/carousel.js +0 -0
  16. package/js/cash.js +0 -0
  17. package/js/characterCounter.js +0 -0
  18. package/js/chips.js +0 -0
  19. package/js/collapsible.js +0 -0
  20. package/js/component.js +0 -0
  21. package/js/datepicker.js +0 -0
  22. package/js/dropdown.js +0 -0
  23. package/js/forms.js +22 -12
  24. package/js/global.js +11 -7
  25. package/js/materialbox.js +0 -0
  26. package/js/modal.js +0 -0
  27. package/js/parallax.js +0 -0
  28. package/js/pushpin.js +0 -0
  29. package/js/range.js +0 -0
  30. package/js/scrollspy.js +0 -0
  31. package/js/select.js +90 -9
  32. package/js/sidenav.js +0 -0
  33. package/js/slider.js +0 -0
  34. package/js/tabs.js +0 -0
  35. package/js/tapTarget.js +0 -0
  36. package/js/timepicker.js +82 -18
  37. package/js/toasts.js +3 -0
  38. package/js/tooltip.js +0 -0
  39. package/js/waves.js +0 -0
  40. package/package.json +8 -6
  41. package/sass/_style.scss +0 -0
  42. package/sass/components/_badges.scss +0 -0
  43. package/sass/components/_buttons.scss +0 -0
  44. package/sass/components/_cards.scss +0 -0
  45. package/sass/components/_carousel.scss +0 -0
  46. package/sass/components/_chips.scss +0 -0
  47. package/sass/components/_collapsible.scss +0 -0
  48. package/sass/components/_collection.scss +0 -0
  49. package/sass/components/_color-classes.scss +0 -0
  50. package/sass/components/_color-variables.scss +0 -0
  51. package/sass/components/_datepicker.scss +0 -0
  52. package/sass/components/_dropdown.scss +0 -0
  53. package/sass/components/_global.scss +4 -0
  54. package/sass/components/_grid.scss +0 -0
  55. package/sass/components/_icons-material-design.scss +0 -0
  56. package/sass/components/_materialbox.scss +0 -0
  57. package/sass/components/_modal.scss +0 -0
  58. package/sass/components/_navbar.scss +0 -0
  59. package/sass/components/_normalize.scss +0 -0
  60. package/sass/components/_preloader.scss +0 -0
  61. package/sass/components/_pulse.scss +0 -0
  62. package/sass/components/_sidenav.scss +0 -0
  63. package/sass/components/_slider.scss +0 -0
  64. package/sass/components/_table_of_contents.scss +0 -0
  65. package/sass/components/_tabs.scss +0 -0
  66. package/sass/components/_tapTarget.scss +0 -0
  67. package/sass/components/_timepicker.scss +27 -11
  68. package/sass/components/_toast.scss +0 -0
  69. package/sass/components/_tooltip.scss +0 -0
  70. package/sass/components/_transitions.scss +0 -0
  71. package/sass/components/_typography.scss +0 -0
  72. package/sass/components/_variables.scss +0 -0
  73. package/sass/components/_waves.scss +0 -0
  74. package/sass/components/forms/_checkboxes.scss +0 -0
  75. package/sass/components/forms/_file-input.scss +0 -0
  76. package/sass/components/forms/_forms.scss +0 -0
  77. package/sass/components/forms/_input-fields.scss +9 -0
  78. package/sass/components/forms/_radio-buttons.scss +0 -0
  79. package/sass/components/forms/_range.scss +0 -0
  80. package/sass/components/forms/_select.scss +0 -0
  81. package/sass/components/forms/_switches.scss +0 -0
  82. package/sass/ghpages-materialize.scss +0 -0
  83. package/sass/materialize.scss +0 -0
@@ -6,7 +6,6 @@
6
6
 
7
7
  /*! nouislider - 9.1.0 - 2016-12-10 16:00:32 */
8
8
 
9
-
10
9
  /* Functional styling;
11
10
  * These styles are required for noUiSlider to function.
12
11
  * You don't need to change these rules to apply your design.
@@ -66,6 +65,7 @@
66
65
  left: -15px;
67
66
  top: -15px;
68
67
  }
68
+
69
69
  /* Painting and performance;
70
70
  * Browsers can paint handles in their own layer.
71
71
  */
@@ -161,7 +161,6 @@
161
161
 
162
162
  /* Disabled state;
163
163
  */
164
-
165
164
  [disabled] .noUi-connect {
166
165
  background: #B8B8B8;
167
166
  }
@@ -369,7 +368,6 @@
369
368
  transform: rotate(135deg);
370
369
  }
371
370
 
372
-
373
371
  .noUi-target.noUi-vertical .noUi-tooltip {
374
372
  position: absolute;
375
373
  height: 30px;
@@ -403,4 +401,4 @@
403
401
  .noUi-horizontal .noUi-active .noUi-tooltip span,
404
402
  .noUi-vertical .noUi-active .noUi-tooltip span {
405
403
  opacity: 1;
406
- }
404
+ }
File without changes
File without changes
package/js/anime.min.js CHANGED
File without changes
File without changes
package/js/buttons.js CHANGED
File without changes
package/js/cards.js CHANGED
File without changes
package/js/carousel.js CHANGED
File without changes
package/js/cash.js CHANGED
File without changes
File without changes
package/js/chips.js CHANGED
File without changes
package/js/collapsible.js CHANGED
File without changes
package/js/component.js CHANGED
File without changes
package/js/datepicker.js CHANGED
File without changes
package/js/dropdown.js CHANGED
File without changes
package/js/forms.js CHANGED
@@ -1,9 +1,23 @@
1
1
  (function($) {
2
+ const TEXT_BASED_INPUT_SELECTOR = [
3
+ 'input:not([type])',
4
+ 'input[type=text]',
5
+ 'input[type=password]',
6
+ 'input[type=email]',
7
+ 'input[type=url]',
8
+ 'input[type=tel]',
9
+ 'input[type=number]',
10
+ 'input[type=search]',
11
+ 'input[type=date]',
12
+ 'input[type=time]',
13
+ 'input[type=month]',
14
+ 'input[type=datetime-local]',
15
+ 'textarea'
16
+ ].join(',');
17
+
2
18
  // Function to update labels of text fields
3
19
  M.updateTextFields = function() {
4
- let input_selector =
5
- 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], input[type=date], input[type=time], textarea';
6
- $(input_selector).each(function(element, index) {
20
+ $(TEXT_BASED_INPUT_SELECTOR).each(function(element, index) {
7
21
  let $this = $(this);
8
22
  if (
9
23
  element.value.length > 0 ||
@@ -138,12 +152,8 @@
138
152
  };
139
153
 
140
154
  $(document).ready(function() {
141
- // Text based inputs
142
- let input_selector =
143
- 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], input[type=date], input[type=time], textarea';
144
-
145
155
  // Add active if form auto complete
146
- $(document).on('change', input_selector, function() {
156
+ $(document).on('change', TEXT_BASED_INPUT_SELECTOR, function() {
147
157
  if (this.value.length !== 0 || $(this).attr('placeholder') !== null) {
148
158
  $(this)
149
159
  .siblings('label')
@@ -162,10 +172,10 @@
162
172
  let formReset = $(e.target);
163
173
  if (formReset.is('form')) {
164
174
  formReset
165
- .find(input_selector)
175
+ .find(TEXT_BASED_INPUT_SELECTOR)
166
176
  .removeClass('valid')
167
177
  .removeClass('invalid');
168
- formReset.find(input_selector).each(function(e) {
178
+ formReset.find(TEXT_BASED_INPUT_SELECTOR).each(function(e) {
169
179
  if (this.value.length) {
170
180
  $(this)
171
181
  .siblings('label')
@@ -192,7 +202,7 @@
192
202
  document.addEventListener(
193
203
  'focus',
194
204
  function(e) {
195
- if ($(e.target).is(input_selector)) {
205
+ if ($(e.target).is(TEXT_BASED_INPUT_SELECTOR)) {
196
206
  $(e.target)
197
207
  .siblings('label, .prefix')
198
208
  .addClass('active');
@@ -209,7 +219,7 @@
209
219
  'blur',
210
220
  function(e) {
211
221
  let $inputElement = $(e.target);
212
- if ($inputElement.is(input_selector)) {
222
+ if ($inputElement.is(TEXT_BASED_INPUT_SELECTOR)) {
213
223
  let selector = '.prefix';
214
224
 
215
225
  if (
package/js/global.js CHANGED
@@ -24,7 +24,7 @@ if (typeof define === 'function' && define.amd) {
24
24
  exports.default = M;
25
25
  }
26
26
 
27
- M.version = '1.0.0';
27
+ M.version = '1.2.0';
28
28
 
29
29
  M.keys = {
30
30
  TAB: 9,
@@ -416,9 +416,13 @@ M.throttle = function(func, wait, options) {
416
416
  /* Feature detection */
417
417
  var passiveIfSupported = false;
418
418
  try {
419
- window.addEventListener("test", null,
420
- Object.defineProperty({}, "passive", {
421
- get: function() { passiveIfSupported = { passive: false }; }
422
- }
423
- ));
424
- } catch(err) {}
419
+ window.addEventListener(
420
+ 'test',
421
+ null,
422
+ Object.defineProperty({}, 'passive', {
423
+ get: function() {
424
+ passiveIfSupported = { passive: false };
425
+ }
426
+ })
427
+ );
428
+ } catch (err) {}
package/js/materialbox.js CHANGED
File without changes
package/js/modal.js CHANGED
File without changes
package/js/parallax.js CHANGED
File without changes
package/js/pushpin.js CHANGED
File without changes
package/js/range.js CHANGED
File without changes
package/js/scrollspy.js CHANGED
File without changes
package/js/select.js CHANGED
@@ -15,6 +15,8 @@
15
15
  this.isMultiple = this.$el.prop('multiple');
16
16
  this.el.tabIndex = -1;
17
17
  this._values = [];
18
+ this.labelEl = null;
19
+ this._labelFor = false;
18
20
  this._setupDropdown();
19
21
  this._setupEventHandlers();
20
22
  }
@@ -29,6 +31,8 @@
29
31
  return domElem.M_FormSelect;
30
32
  }
31
33
  destroy() {
34
+ // Returns label to its original owner
35
+ if (this._labelFor) this.labelEl.setAttribute("for", this.el.id);
32
36
  this._removeEventHandlers();
33
37
  this._removeDropdown();
34
38
  this.el.M_FormSelect = undefined;
@@ -41,6 +45,9 @@
41
45
  .find('li:not(.optgroup)')
42
46
  .each((el) => {
43
47
  el.addEventListener('click', this._handleOptionClickBound);
48
+ el.addEventListener('keydown', (e) => {
49
+ if (e.key === " " || e.key === "Enter") this._handleOptionClickBound(e);
50
+ });
44
51
  });
45
52
  this.el.addEventListener('change', this._handleSelectChangeBound);
46
53
  this.input.addEventListener('click', this._handleInputClickBound);
@@ -95,7 +102,7 @@
95
102
  if (!this.isMultiple) this.dropdown.close();
96
103
  }
97
104
  _handleInputClick() {
98
- if (this.dropdown && this.dropdown.isOpen) {
105
+ if (this.dropdown && this.dropdown.isOpen) {
99
106
  this._setValueToInput();
100
107
  this._setSelectedStates();
101
108
  }
@@ -119,6 +126,9 @@
119
126
  $(this.dropdownOptions).addClass(
120
127
  'dropdown-content select-dropdown ' + (this.isMultiple ? 'multiple-select-dropdown' : '')
121
128
  );
129
+ this.dropdownOptions.setAttribute("role", "listbox");
130
+ this.dropdownOptions.setAttribute("aria-required", this.el.hasAttribute("required"));
131
+ this.dropdownOptions.setAttribute("aria-multiselectable", this.isMultiple);
122
132
 
123
133
  // Create dropdown structure
124
134
  if (this.$selectOptions.length) {
@@ -133,18 +143,23 @@
133
143
  } else if ($(realOption).is('optgroup')) {
134
144
  // Optgroup
135
145
  const selectOptions = $(realOption).children('option');
136
- $(this.dropdownOptions).append(
137
- $(
138
- '<li class="optgroup"><span>' + realOption.getAttribute('label') + '</span></li>'
139
- )[0]
140
- );
146
+ let lId = "opt-group-" + M.guid();
147
+ let groupParent = $(
148
+ `<li class="optgroup" role="group" aria-labelledby="${lId}" tabindex="-1"><span id="${lId}" role="presentation">${realOption.getAttribute('label')}</span></li>`
149
+ )[0];
150
+ let groupChildren = [];
151
+ $(this.dropdownOptions).append(groupParent);
141
152
  selectOptions.each((realOption) => {
142
153
  const virtualOption = this._createAndAppendOptionWithIcon(
143
154
  realOption,
144
155
  'optgroup-option'
145
156
  );
157
+ let cId = "opt-child-" + M.guid();
158
+ virtualOption.id = cId;
159
+ groupChildren.push(cId);
146
160
  this._addOptionToValues(realOption, virtualOption);
147
161
  });
162
+ groupParent.setAttribute("aria-owns", groupChildren.join(" "));
148
163
  }
149
164
  });
150
165
  }
@@ -152,18 +167,62 @@
152
167
 
153
168
  // Add input dropdown
154
169
  this.input = document.createElement('input');
170
+ this.input.id = "m_select-input-" + M.guid();
155
171
  $(this.input).addClass('select-dropdown dropdown-trigger');
156
172
  this.input.setAttribute('type', 'text');
157
173
  this.input.setAttribute('readonly', 'true');
158
174
  this.input.setAttribute('data-target', this.dropdownOptions.id);
175
+ this.input.setAttribute('aria-readonly', 'true');
159
176
  if (this.el.disabled) $(this.input).prop('disabled', 'true');
160
177
 
178
+ // Makes new element to assume HTML's select label and
179
+ // aria-attributes, if exists
180
+ if (this.el.hasAttribute("aria-labelledby")){
181
+ this.labelEl = document.getElementById(this.el.getAttribute("aria-labelledby"));
182
+ }
183
+ else if (this.el.id != ""){
184
+ let lbl = $(`label[for='${this.el.id}']`);
185
+ if (lbl.length){
186
+ this.labelEl = lbl[0];
187
+ this.labelEl.removeAttribute("for");
188
+ this._labelFor = true;
189
+ }
190
+ }
191
+ // Tries to find a valid label in parent element
192
+ if (!this.labelEl){
193
+ let el = this.el.parentElement;
194
+ if (el) el = el.getElementsByTagName("label")[0];
195
+ if (el) this.labelEl = el;
196
+ }
197
+ if (this.labelEl && this.labelEl.id == ""){
198
+ this.labelEl.id = "m_select-label-" + M.guid();
199
+ }
200
+
201
+ if (this.labelEl){
202
+ this.labelEl.setAttribute("for", this.input.id);
203
+ this.dropdownOptions.setAttribute("aria-labelledby", this.labelEl.id);
204
+ }
205
+ else this.dropdownOptions.setAttribute("aria-label", "");
206
+
207
+ let attrs = this.el.attributes;
208
+ for (let i = 0; i < attrs.length; ++i){
209
+ const attr = attrs[i];
210
+ if (attr.name.startsWith("aria-"))
211
+ this.input.setAttribute(attr.name, attr.value);
212
+ }
213
+
214
+ // Adds aria-attributes to input element
215
+ this.input.setAttribute("role", "combobox");
216
+ this.input.setAttribute("aria-owns", this.dropdownOptions.id);
217
+ this.input.setAttribute("aria-controls", this.dropdownOptions.id);
218
+ this.input.setAttribute("aria-expanded", false);
219
+
161
220
  $(this.wrapper).prepend(this.input);
162
221
  this._setValueToInput();
163
222
 
164
223
  // Add caret
165
224
  let dropdownIcon = $(
166
- '<svg class="caret" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>'
225
+ '<svg class="caret" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>'
167
226
  );
168
227
  $(this.wrapper).prepend(dropdownIcon[0]);
169
228
  // Initialize dropdown
@@ -171,6 +230,7 @@
171
230
  let dropdownOptions = $.extend({}, this.options.dropdownOptions);
172
231
  dropdownOptions.coverTrigger = false;
173
232
  let userOnOpenEnd = dropdownOptions.onOpenEnd;
233
+ let userOnCloseEnd = dropdownOptions.onCloseEnd;
174
234
  // Add callback for centering selected option when dropdown content is scrollable
175
235
  dropdownOptions.onOpenEnd = (el) => {
176
236
  let selectedOption = $(this.dropdownOptions)
@@ -191,10 +251,20 @@
191
251
  this.dropdownOptions.scrollTop = scrollOffset;
192
252
  }
193
253
  }
254
+ // Sets "aria-expanded" to "true"
255
+ this.input.setAttribute("aria-expanded", true);
194
256
  // Handle user declared onOpenEnd if needed
195
257
  if (userOnOpenEnd && typeof userOnOpenEnd === 'function')
196
258
  userOnOpenEnd.call(this.dropdown, this.el);
197
259
  };
260
+ // Add callback for reseting "expanded" state
261
+ dropdownOptions.onCloseEnd = (el) => {
262
+ // Sets "aria-expanded" to "false"
263
+ this.input.setAttribute("aria-expanded", false);
264
+ // Handle user declared onOpenEnd if needed
265
+ if (userOnCloseEnd && typeof userOnCloseEnd === 'function')
266
+ userOnCloseEnd.call(this.dropdown, this.el);
267
+ };
198
268
  // Prevent dropdown from closing too early
199
269
  dropdownOptions.closeOnClick = false;
200
270
  this.dropdown = M.Dropdown.init(this.input, dropdownOptions);
@@ -216,7 +286,11 @@
216
286
  }
217
287
  _createAndAppendOptionWithIcon(realOption, type) {
218
288
  const li = document.createElement('li');
219
- if (realOption.disabled) li.classList.add('disabled');
289
+ li.setAttribute("role", "option");
290
+ if (realOption.disabled){
291
+ li.classList.add('disabled');
292
+ li.setAttribute("aria-disabled", true);
293
+ }
220
294
  if (type === 'optgroup-option') li.classList.add(type);
221
295
  // Text / Checkbox
222
296
  const span = document.createElement('span');
@@ -231,6 +305,7 @@
231
305
  const classes = realOption.getAttribute('class');
232
306
  if (iconUrl) {
233
307
  const img = $(`<img alt="" class="${classes}" src="${iconUrl}">`);
308
+ img[0].setAttribute("aria-hidden", true);
234
309
  li.prepend(img[0]);
235
310
  }
236
311
  // Check for multiple type
@@ -241,12 +316,14 @@
241
316
  _selectValue(value) {
242
317
  value.el.selected = true;
243
318
  value.optionEl.classList.add('selected');
319
+ value.optionEl.setAttribute("aria-selected", true);
244
320
  const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
245
321
  if (checkbox) checkbox.checked = true;
246
322
  }
247
323
  _deselectValue(value) {
248
324
  value.el.selected = false;
249
325
  value.optionEl.classList.remove('selected');
326
+ value.optionEl.setAttribute("aria-selected", false);
250
327
  const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
251
328
  if (checkbox) checkbox.checked = false;
252
329
  }
@@ -290,13 +367,17 @@
290
367
  .prop('checked', optionIsSelected);
291
368
  if (optionIsSelected) {
292
369
  this._activateOption($(this.dropdownOptions), $(value.optionEl));
293
- } else $(value.optionEl).removeClass('selected');
370
+ } else {
371
+ $(value.optionEl).removeClass('selected');
372
+ $(value.optionEl).attr("aria-selected", false);
373
+ }
294
374
  });
295
375
  }
296
376
  _activateOption(ul, li) {
297
377
  if (!li) return;
298
378
  if (!this.isMultiple) ul.find('li.selected').removeClass('selected');
299
379
  $(li).addClass('selected');
380
+ $(li).attr("aria-selected", true);
300
381
  }
301
382
 
302
383
  getSelectedValues() {
package/js/sidenav.js CHANGED
File without changes
package/js/slider.js CHANGED
File without changes
package/js/tabs.js CHANGED
File without changes
package/js/tapTarget.js CHANGED
File without changes
package/js/timepicker.js CHANGED
@@ -116,14 +116,16 @@
116
116
  this._handleClockClickStartBound = this._handleClockClickStart.bind(this);
117
117
  this._handleDocumentClickMoveBound = this._handleDocumentClickMove.bind(this);
118
118
  this._handleDocumentClickEndBound = this._handleDocumentClickEnd.bind(this);
119
+ this._inputFromTextFieldBound = this._handleTimeInputEnterKey.bind(this);
119
120
 
120
121
  this.el.addEventListener('click', this._handleInputClickBound);
121
122
  this.el.addEventListener('keydown', this._handleInputKeydownBound);
122
123
  this.plate.addEventListener('mousedown', this._handleClockClickStartBound);
123
124
  this.plate.addEventListener('touchstart', this._handleClockClickStartBound);
125
+ this.digitalClock.addEventListener('keyup', this._inputFromTextFieldBound);
124
126
 
125
- $(this.spanHours).on('click', this.showView.bind(this, 'hours'));
126
- $(this.spanMinutes).on('click', this.showView.bind(this, 'minutes'));
127
+ $(this.inputHours).on('click', this.showView.bind(this, 'hours'));
128
+ $(this.inputMinutes).on('click', this.showView.bind(this, 'minutes'));
127
129
  }
128
130
 
129
131
  _removeEventHandlers() {
@@ -142,6 +144,13 @@
142
144
  }
143
145
  }
144
146
 
147
+ _handleTimeInputEnterKey(e) {
148
+ if (e.which === M.keys.ENTER) {
149
+ e.preventDefault();
150
+ this._inputFromTextField();
151
+ }
152
+ }
153
+
145
154
  _handleClockClickStart(e) {
146
155
  e.preventDefault();
147
156
  let clockPlateBR = this.plate.getBoundingClientRect();
@@ -211,7 +220,7 @@
211
220
 
212
221
  // Append popover to input by default
213
222
  const optEl = this.options.container;
214
- let containerEl = (optEl instanceof HTMLElement?optEl:document.querySelector(optEl));
223
+ let containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);
215
224
  if (this.options.container && !!containerEl) {
216
225
  this.$modalEl.appendTo(containerEl);
217
226
  } else {
@@ -238,16 +247,17 @@
238
247
  this.vibrate = navigator.vibrate
239
248
  ? 'vibrate'
240
249
  : navigator.webkitVibrate
241
- ? 'webkitVibrate'
242
- : null;
250
+ ? 'webkitVibrate'
251
+ : null;
243
252
 
244
253
  this._canvas = this.modalEl.querySelector('.timepicker-canvas');
245
254
  this.plate = this.modalEl.querySelector('.timepicker-plate');
255
+ this.digitalClock = this.modalEl.querySelector('.timepicker-display-column');
246
256
 
247
257
  this.hoursView = this.modalEl.querySelector('.timepicker-hours');
248
258
  this.minutesView = this.modalEl.querySelector('.timepicker-minutes');
249
- this.spanHours = this.modalEl.querySelector('.timepicker-span-hours');
250
- this.spanMinutes = this.modalEl.querySelector('.timepicker-span-minutes');
259
+ this.inputHours = this.modalEl.querySelector('.timepicker-input-hours');
260
+ this.inputMinutes = this.modalEl.querySelector('.timepicker-input-minutes');
251
261
  this.spanAmPm = this.modalEl.querySelector('.timepicker-span-am-pm');
252
262
  this.footer = this.modalEl.querySelector('.timepicker-footer');
253
263
  this.amOrPm = 'PM';
@@ -341,7 +351,7 @@
341
351
  if (this.options.twelveHour) {
342
352
  for (let i = 1; i < 13; i += 1) {
343
353
  let tick = $tick.clone();
344
- let radian = i / 6 * Math.PI;
354
+ let radian = (i / 6) * Math.PI;
345
355
  let radius = this.options.outerRadius;
346
356
  tick.css({
347
357
  left:
@@ -356,7 +366,7 @@
356
366
  } else {
357
367
  for (let i = 0; i < 24; i += 1) {
358
368
  let tick = $tick.clone();
359
- let radian = i / 6 * Math.PI;
369
+ let radian = (i / 6) * Math.PI;
360
370
  let inner = i > 0 && i < 13;
361
371
  let radius = inner ? this.options.innerRadius : this.options.outerRadius;
362
372
  tick.css({
@@ -377,7 +387,7 @@
377
387
  // Minutes view
378
388
  for (let i = 0; i < 60; i += 5) {
379
389
  let tick = $tick.clone();
380
- let radian = i / 30 * Math.PI;
390
+ let radian = (i / 30) * Math.PI;
381
391
  tick.css({
382
392
  left:
383
393
  this.options.dialRadius +
@@ -428,8 +438,8 @@
428
438
  }
429
439
  this.hours = +value[0] || 0;
430
440
  this.minutes = +value[1] || 0;
431
- this.spanHours.innerHTML = this.hours;
432
- this.spanMinutes.innerHTML = Timepicker._addLeadingZero(this.minutes);
441
+ this.inputHours.value = this.hours;
442
+ this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes);
433
443
 
434
444
  this._updateAmPmView();
435
445
  }
@@ -443,8 +453,8 @@
443
453
  hideView = isHours ? this.minutesView : this.hoursView;
444
454
  this.currentView = view;
445
455
 
446
- $(this.spanHours).toggleClass('text-primary', isHours);
447
- $(this.spanMinutes).toggleClass('text-primary', !isHours);
456
+ $(this.inputHours).toggleClass('text-primary', isHours);
457
+ $(this.inputMinutes).toggleClass('text-primary', !isHours);
448
458
 
449
459
  // Transition view
450
460
  hideView.classList.add('timepicker-dial-out');
@@ -485,6 +495,60 @@
485
495
  }
486
496
  }
487
497
 
498
+ _inputFromTextField() {
499
+ const isHours = this.currentView === 'hours';
500
+
501
+ if (isHours) {
502
+ const value = this['inputHours'].value;
503
+
504
+ if (value > 0 && value < 13) {
505
+ this.drawClockFromTimeInput(value, isHours);
506
+
507
+ this.showView('minutes', this.options.duration / 2);
508
+
509
+ this.hours = value;
510
+ this.inputMinutes.focus();
511
+ } else {
512
+ const hour = new Date().getHours();
513
+ this['inputHours'].value = hour % 12;
514
+ }
515
+ } else {
516
+ const value = this['inputMinutes'].value;
517
+
518
+ if (value >= 0 && value < 60) {
519
+ this['inputMinutes'].value = Timepicker._addLeadingZero(value);
520
+
521
+ this.drawClockFromTimeInput(value, isHours);
522
+
523
+ this.minutes = value;
524
+ this.modalEl.querySelector('.confirmation-btns :nth-child(2)').focus();
525
+ } else {
526
+ const minutes = new Date().getMinutes();
527
+ this['inputMinutes'].value = Timepicker._addLeadingZero(minutes);
528
+ }
529
+ }
530
+ }
531
+
532
+ drawClockFromTimeInput(value, isHours) {
533
+ const unit = Math.PI / (isHours ? 6 : 30);
534
+ const radian = value * unit;
535
+ let radius;
536
+
537
+ if (this.options.twelveHour) {
538
+ radius = this.options.outerRadius;
539
+ }
540
+
541
+ let cx1 = Math.sin(radian) * (radius - this.options.tickRadius),
542
+ cy1 = -Math.cos(radian) * (radius - this.options.tickRadius),
543
+ cx2 = Math.sin(radian) * radius,
544
+ cy2 = -Math.cos(radian) * radius;
545
+
546
+ this.hand.setAttribute('x2', cx1);
547
+ this.hand.setAttribute('y2', cy1);
548
+ this.bg.setAttribute('cx', cx2);
549
+ this.bg.setAttribute('cy', cy2);
550
+ }
551
+
488
552
  setHand(x, y, roundBy5) {
489
553
  let radian = Math.atan2(x, -y),
490
554
  isHours = this.currentView === 'hours',
@@ -547,9 +611,9 @@
547
611
 
548
612
  this[this.currentView] = value;
549
613
  if (isHours) {
550
- this['spanHours'].innerHTML = value;
614
+ this['inputHours'].value = value;
551
615
  } else {
552
- this['spanMinutes'].innerHTML = Timepicker._addLeadingZero(value);
616
+ this['inputMinutes'].value = Timepicker._addLeadingZero(value);
553
617
  }
554
618
 
555
619
  // Set clock hand and others' position
@@ -619,9 +683,9 @@
619
683
  '<div class="timepicker-digital-display">',
620
684
  '<div class="timepicker-text-container">',
621
685
  '<div class="timepicker-display-column">',
622
- '<span class="timepicker-span-hours text-primary"></span>',
686
+ '<input type="text" maxlength="2" autofocus class="timepicker-input-hours text-primary" />',
623
687
  ':',
624
- '<span class="timepicker-span-minutes"></span>',
688
+ '<input type="text" maxlength="2" class="timepicker-input-minutes" />',
625
689
  '</div>',
626
690
  '<div class="timepicker-display-column timepicker-display-am-pm">',
627
691
  '<div class="timepicker-span-am-pm"></div>',
package/js/toasts.js CHANGED
@@ -194,6 +194,9 @@
194
194
  _createToast() {
195
195
  let toast = document.createElement('div');
196
196
  toast.classList.add('toast');
197
+ toast.setAttribute('role', 'alert');
198
+ toast.setAttribute('aria-live', 'assertive');
199
+ toast.setAttribute('aria-atomic', true);
197
200
 
198
201
  // Add custom classes onto toast
199
202
  if (!!this.options.classes.length) {
package/js/tooltip.js CHANGED
File without changes
package/js/waves.js CHANGED
File without changes