@materializecss/materialize 2.0.3-alpha → 2.0.3

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/css/materialize.css +345 -236
  3. package/dist/css/materialize.min.css +2 -2
  4. package/dist/js/materialize.js +518 -1979
  5. package/dist/js/materialize.min.js +2 -2
  6. package/dist/js/materialize.min.js.map +1 -1
  7. package/dist/src/buttons.d.ts.map +1 -1
  8. package/dist/src/cards.d.ts.map +1 -1
  9. package/dist/src/collapsible.d.ts +1 -0
  10. package/dist/src/collapsible.d.ts.map +1 -1
  11. package/dist/src/dropdown.d.ts.map +1 -1
  12. package/dist/src/global.d.ts.map +1 -1
  13. package/dist/src/materialbox.d.ts +14 -10
  14. package/dist/src/materialbox.d.ts.map +1 -1
  15. package/dist/src/modal.d.ts.map +1 -1
  16. package/dist/src/range.d.ts.map +1 -1
  17. package/dist/src/scrollspy.d.ts.map +1 -1
  18. package/dist/src/sidenav.d.ts +25 -25
  19. package/dist/src/sidenav.d.ts.map +1 -1
  20. package/dist/src/slider.d.ts +12 -12
  21. package/dist/src/slider.d.ts.map +1 -1
  22. package/dist/src/tabs.d.ts +1 -1
  23. package/dist/src/tabs.d.ts.map +1 -1
  24. package/dist/src/toasts.d.ts +7 -2
  25. package/dist/src/toasts.d.ts.map +1 -1
  26. package/dist/src/tooltip.d.ts +8 -2
  27. package/dist/src/tooltip.d.ts.map +1 -1
  28. package/package.json +14 -13
  29. package/sass/components/_buttons.scss +158 -73
  30. package/sass/components/_chips.scss +75 -28
  31. package/sass/components/_collapsible.scss +14 -2
  32. package/sass/components/_global.scss +6 -94
  33. package/sass/components/_materialbox.scss +2 -2
  34. package/sass/components/_modal.scss +0 -1
  35. package/sass/components/_preloader.scss +85 -0
  36. package/sass/components/_tooltip.scss +18 -8
  37. package/sass/components/_variables.scss +5 -4
  38. package/sass/components/forms/_range.scss +1 -1
  39. package/sass/components/forms/_switches.scss +44 -14
  40. package/Gruntfile.js +0 -480
  41. package/src/autocomplete.ts +0 -553
  42. package/src/bounding.ts +0 -6
  43. package/src/buttons.ts +0 -260
  44. package/src/cards.ts +0 -53
  45. package/src/carousel.ts +0 -676
  46. package/src/characterCounter.ts +0 -117
  47. package/src/chips.ts +0 -439
  48. package/src/collapsible.ts +0 -249
  49. package/src/component.ts +0 -120
  50. package/src/datepicker.ts +0 -1076
  51. package/src/dropdown.ts +0 -644
  52. package/src/edges.ts +0 -6
  53. package/src/forms.ts +0 -132
  54. package/src/global.ts +0 -114
  55. package/src/index.ts +0 -26
  56. package/src/materialbox.ts +0 -404
  57. package/src/modal.ts +0 -341
  58. package/src/parallax.ts +0 -149
  59. package/src/pushpin.ts +0 -165
  60. package/src/range.ts +0 -198
  61. package/src/scrollspy.ts +0 -263
  62. package/src/select.ts +0 -484
  63. package/src/sidenav.ts +0 -543
  64. package/src/slider.ts +0 -474
  65. package/src/tabs.ts +0 -347
  66. package/src/tapTarget.ts +0 -273
  67. package/src/timepicker.ts +0 -832
  68. package/src/toasts.ts +0 -290
  69. package/src/tooltip.ts +0 -346
  70. package/src/utils.ts +0 -271
  71. package/src/waves.ts +0 -70
package/src/timepicker.ts DELETED
@@ -1,832 +0,0 @@
1
- import { Modal } from "./modal";
2
- import { Utils } from "./utils";
3
- import { Component, BaseOptions, InitElements, MElement, I18nOptions } from "./component";
4
-
5
- export type Views = "hours" | "minutes";
6
-
7
- export interface TimepickerOptions extends BaseOptions {
8
- /**
9
- * Dial radius.
10
- * @default 135
11
- */
12
- dialRadius: number;
13
- /**
14
- * Outer radius.
15
- * @default 105
16
- */
17
- outerRadius: number;
18
- /**
19
- * Inner radius.
20
- * @default 70
21
- */
22
- innerRadius: number;
23
- /**
24
- * Tick radius.
25
- * @default 20
26
- */
27
- tickRadius: number;
28
- /**
29
- * Duration of the transition from/to the hours/minutes view.
30
- * @default 350
31
- */
32
- duration: number;
33
- /**
34
- * Specify a DOM element OR selector for a DOM element to render
35
- * the time picker in, by default it will be placed before the input.
36
- * @default null
37
- */
38
- container: HTMLElement | string | null;
39
- /**
40
- * Show the clear button in the Timepicker.
41
- * @default false
42
- */
43
- showClearBtn: boolean;
44
- /**
45
- * Default time to set on the timepicker 'now' or '13:14'.
46
- * @default 'now';
47
- */
48
- defaultTime: string;
49
- /**
50
- * Millisecond offset from the defaultTime.
51
- * @default 0
52
- */
53
- fromNow: number;
54
- /**
55
- * Internationalization options.
56
- */
57
- i18n: Partial<I18nOptions>;
58
- /**
59
- * Automatically close picker when minute is selected.
60
- * @default false;
61
- */
62
- autoClose: boolean;
63
- /**
64
- * Use 12 hour AM/PM clock instead of 24 hour clock.
65
- * @default true
66
- */
67
- twelveHour: boolean;
68
- /**
69
- * Vibrate device when dragging clock hand.
70
- * @default true
71
- */
72
- vibrate: boolean;
73
- /**
74
- * Callback function called before modal is opened.
75
- * @default null
76
- */
77
- onOpenStart: (el: HTMLElement) => void;
78
- /**
79
- * Callback function called after modal is opened.
80
- * @default null
81
- */
82
- onOpenEnd: (el: HTMLElement) => void;
83
- /**
84
- * Callback function called before modal is closed.
85
- * @default null
86
- */
87
- onCloseStart: (el: HTMLElement) => void;
88
- /**
89
- * Callback function called after modal is closed.
90
- * @default null
91
- */
92
- onCloseEnd: (el: HTMLElement) => void;
93
- /**
94
- * Callback function when a time is selected.
95
- * @default null
96
- */
97
- onSelect: (hour: number, minute: number) => void;
98
- }
99
-
100
- let _defaults: TimepickerOptions = {
101
- dialRadius: 135,
102
- outerRadius: 105,
103
- innerRadius: 70,
104
- tickRadius: 20,
105
- duration: 350,
106
- container: null,
107
- defaultTime: 'now', // default time, 'now' or '13:14' e.g.
108
- fromNow: 0, // Millisecond offset from the defaultTime
109
- showClearBtn: false,
110
- // internationalization
111
- i18n: {
112
- cancel: 'Cancel',
113
- clear: 'Clear',
114
- done: 'Ok'
115
- },
116
- autoClose: false, // auto close when minute is selected
117
- twelveHour: true, // change to 12 hour AM/PM clock from 24 hour
118
- vibrate: true, // vibrate the device when dragging clock hand
119
- // Callbacks
120
- onOpenStart: null,
121
- onOpenEnd: null,
122
- onCloseStart: null,
123
- onCloseEnd: null,
124
- onSelect: null
125
- };
126
-
127
- type Point = {
128
- x: number,
129
- y: number
130
- };
131
-
132
- export class Timepicker extends Component<TimepickerOptions> {
133
- declare el: HTMLInputElement;
134
- id: string;
135
- modal: Modal;
136
- modalEl: HTMLElement;
137
- plate: any;
138
- digitalClock: any;
139
- inputHours: HTMLInputElement;
140
- inputMinutes: HTMLInputElement;
141
- x0: number;
142
- y0: number;
143
- moved: boolean;
144
- dx: number;
145
- dy: number;
146
- /**
147
- * Current view on the timepicker.
148
- * @default 'hours'
149
- */
150
- currentView: Views;
151
- hand: any;
152
- minutesView: HTMLElement;
153
- hours: any;
154
- minutes: any;
155
- /** The selected time. */
156
- time: string;
157
- /**
158
- * If the time is AM or PM on twelve-hour clock.
159
- * @default 'PM'
160
- */
161
- amOrPm: "AM" | "PM";
162
- static _template: any;
163
- /** If the picker is open. */
164
- isOpen: boolean;
165
- /** Vibrate device when dragging clock hand. */
166
- vibrate: "vibrate" | "webkitVibrate" | null;
167
- _canvas: HTMLElement;
168
- hoursView: any;
169
- spanAmPm: HTMLSpanElement;
170
- footer: HTMLElement;
171
- private _amBtn: HTMLElement;
172
- private _pmBtn: HTMLElement;
173
- bg: Element;
174
- bearing: Element;
175
- g: Element;
176
- toggleViewTimer: string | number | NodeJS.Timeout;
177
- canvas: any;
178
- vibrateTimer: any;
179
-
180
- constructor(el: HTMLInputElement, options: Partial<TimepickerOptions>) {
181
- super(el, options, Timepicker);
182
- (this.el as any).M_Timepicker = this;
183
-
184
- this.options = {
185
- ...Timepicker.defaults,
186
- ...options
187
- };
188
-
189
- this.id = Utils.guid();
190
- this._insertHTMLIntoDOM();
191
- this._setupModal();
192
- this._setupVariables();
193
- this._setupEventHandlers();
194
- this._clockSetup();
195
- this._pickerSetup();
196
- }
197
-
198
- static get defaults(): TimepickerOptions {
199
- return _defaults;
200
- }
201
-
202
- /**
203
- * Initializes instance of Timepicker.
204
- * @param el HTML element.
205
- * @param options Component options.
206
- */
207
- static init(el: HTMLInputElement, options?: Partial<TimepickerOptions>): Timepicker;
208
- /**
209
- * Initializes instances of Timepicker.
210
- * @param els HTML elements.
211
- * @param options Component options.
212
- */
213
- static init(els: InitElements<HTMLInputElement | MElement>, options?: Partial<TimepickerOptions>): Timepicker[];
214
- /**
215
- * Initializes instances of Timepicker.
216
- * @param els HTML elements.
217
- * @param options Component options.
218
- */
219
- static init(els: HTMLInputElement | InitElements<HTMLInputElement | MElement>, options: Partial<TimepickerOptions> = {}): Timepicker | Timepicker[] {
220
- return super.init(els, options, Timepicker);
221
- }
222
-
223
- static _addLeadingZero(num: number) {
224
- return (num < 10 ? '0' : '') + num;
225
- }
226
-
227
- static _createSVGEl(name: string) {
228
- let svgNS = 'http://www.w3.org/2000/svg';
229
- return document.createElementNS(svgNS, name);
230
- }
231
-
232
- static _Pos(e: TouchEvent | MouseEvent): Point {
233
- if (e.type.startsWith("touch") && (e as TouchEvent).targetTouches.length >= 1) {
234
- return { x: (e as TouchEvent).targetTouches[0].clientX, y: (e as TouchEvent).targetTouches[0].clientY };
235
- }
236
- // mouse event
237
- return { x: (e as MouseEvent).clientX, y: (e as MouseEvent).clientY };
238
- }
239
-
240
- static getInstance(el: HTMLElement): Timepicker {
241
- return (el as any).M_Timepicker;
242
- }
243
-
244
- destroy() {
245
- this._removeEventHandlers();
246
- this.modal.destroy();
247
- this.modalEl.remove();
248
- (this.el as any).M_Timepicker = undefined;
249
- }
250
-
251
- _setupEventHandlers() {
252
- this.el.addEventListener('click', this._handleInputClick);
253
- this.el.addEventListener('keydown', this._handleInputKeydown);
254
- this.plate.addEventListener('mousedown', this._handleClockClickStart);
255
- this.plate.addEventListener('touchstart', this._handleClockClickStart);
256
- this.digitalClock.addEventListener('keyup', this._inputFromTextField);
257
- this.inputHours.addEventListener('click', () => this.showView('hours'));
258
- this.inputMinutes.addEventListener('click', () => this.showView('minutes'));
259
- }
260
-
261
- _removeEventHandlers() {
262
- this.el.removeEventListener('click', this._handleInputClick);
263
- this.el.removeEventListener('keydown', this._handleInputKeydown);
264
- }
265
-
266
- _handleInputClick = () => {
267
- this.open();
268
- }
269
-
270
- _handleInputKeydown = (e: KeyboardEvent) => {
271
- if (Utils.keys.ENTER.includes(e.key)) {
272
- e.preventDefault();
273
- this.open();
274
- }
275
- }
276
-
277
- _handleTimeInputEnterKey = (e: KeyboardEvent) => {
278
- if (Utils.keys.ENTER.includes(e.key)) {
279
- e.preventDefault();
280
- this._inputFromTextField();
281
- }
282
- }
283
-
284
- _handleClockClickStart = (e) => {
285
- e.preventDefault();
286
- let clockPlateBR = this.plate.getBoundingClientRect();
287
- let offset = { x: clockPlateBR.left, y: clockPlateBR.top };
288
-
289
- this.x0 = offset.x + this.options.dialRadius;
290
- this.y0 = offset.y + this.options.dialRadius;
291
- this.moved = false;
292
- let clickPos = Timepicker._Pos(e);
293
- this.dx = clickPos.x - this.x0;
294
- this.dy = clickPos.y - this.y0;
295
-
296
- // Set clock hands
297
- this.setHand(this.dx, this.dy, false);
298
- // Mousemove on document
299
- document.addEventListener('mousemove', this._handleDocumentClickMove);
300
- document.addEventListener('touchmove', this._handleDocumentClickMove);
301
- // Mouseup on document
302
- document.addEventListener('mouseup', this._handleDocumentClickEnd);
303
- document.addEventListener('touchend', this._handleDocumentClickEnd);
304
- }
305
-
306
- _handleDocumentClickMove = (e) => {
307
- e.preventDefault();
308
- let clickPos = Timepicker._Pos(e);
309
- let x = clickPos.x - this.x0;
310
- let y = clickPos.y - this.y0;
311
- this.moved = true;
312
- this.setHand(x, y, false);
313
- }
314
-
315
- _handleDocumentClickEnd = (e) => {
316
- e.preventDefault();
317
- document.removeEventListener('mouseup', this._handleDocumentClickEnd);
318
- document.removeEventListener('touchend', this._handleDocumentClickEnd);
319
- let clickPos = Timepicker._Pos(e);
320
- let x = clickPos.x - this.x0;
321
- let y = clickPos.y - this.y0;
322
- if (this.moved && x === this.dx && y === this.dy) {
323
- this.setHand(x, y);
324
- }
325
- if (this.currentView === 'hours') {
326
- this.showView('minutes', this.options.duration / 2);
327
- }
328
- else if (this.options.autoClose) {
329
- this.minutesView.classList.add('timepicker-dial-out');
330
- setTimeout(() => {
331
- this.done();
332
- }, this.options.duration / 2);
333
- }
334
- if (typeof this.options.onSelect === 'function') {
335
- this.options.onSelect.call(this, this.hours, this.minutes);
336
- }
337
- // Unbind mousemove event
338
- document.removeEventListener('mousemove', this._handleDocumentClickMove);
339
- document.removeEventListener('touchmove', this._handleDocumentClickMove);
340
- }
341
-
342
- _insertHTMLIntoDOM() {
343
- const template = document.createElement('template');
344
- template.innerHTML = Timepicker._template.trim();
345
- this.modalEl = <HTMLElement>template.content.firstChild;
346
- this.modalEl.id = 'modal-' + this.id;
347
-
348
- // Append popover to input by default
349
- const optEl = this.options.container;
350
- const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);
351
-
352
- if (this.options.container && !!containerEl) {
353
- containerEl.append(this.modalEl);
354
- }
355
- else {
356
- this.el.parentElement.appendChild(this.modalEl);
357
- }
358
- }
359
-
360
- _setupModal() {
361
- this.modal = Modal.init(this.modalEl, {
362
- onOpenStart: this.options.onOpenStart,
363
- onOpenEnd: this.options.onOpenEnd,
364
- onCloseStart: this.options.onCloseStart,
365
- onCloseEnd: () => {
366
- if (typeof this.options.onCloseEnd === 'function') {
367
- this.options.onCloseEnd.call(this);
368
- }
369
- this.isOpen = false;
370
- }
371
- });
372
- }
373
-
374
- _setupVariables() {
375
- this.currentView = 'hours';
376
- this.vibrate = navigator.vibrate
377
- ? 'vibrate'
378
- : (navigator as any).webkitVibrate
379
- ? 'webkitVibrate'
380
- : null;
381
- this._canvas = this.modalEl.querySelector('.timepicker-canvas');
382
- this.plate = this.modalEl.querySelector('.timepicker-plate');
383
- this.digitalClock = this.modalEl.querySelector('.timepicker-display-column');
384
- this.hoursView = this.modalEl.querySelector('.timepicker-hours');
385
- this.minutesView = this.modalEl.querySelector('.timepicker-minutes');
386
- this.inputHours = this.modalEl.querySelector('.timepicker-input-hours');
387
- this.inputMinutes = this.modalEl.querySelector('.timepicker-input-minutes');
388
- this.spanAmPm = this.modalEl.querySelector('.timepicker-span-am-pm');
389
- this.footer = this.modalEl.querySelector('.timepicker-footer');
390
- this.amOrPm = 'PM';
391
- }
392
-
393
- private _createButton(text: string, visibility: string): HTMLButtonElement {
394
- const button = document.createElement('button');
395
- button.classList.add('btn-flat', 'waves-effect');
396
- button.style.visibility = visibility;
397
- button.type = 'button';
398
- button.tabIndex = this.options.twelveHour ? 3 : 1;
399
- button.innerText = text;
400
- return button;
401
- }
402
-
403
- _pickerSetup() {
404
- const clearButton = this._createButton(this.options.i18n.clear, this.options.showClearBtn ? '' : 'hidden');
405
- clearButton.classList.add('timepicker-clear');
406
- clearButton.addEventListener('click', this.clear);
407
- this.footer.appendChild(clearButton);
408
-
409
- const confirmationBtnsContainer = document.createElement('div');
410
- confirmationBtnsContainer.classList.add('confirmation-btns');
411
- this.footer.append(confirmationBtnsContainer);
412
-
413
- const cancelButton = this._createButton(this.options.i18n.cancel, '');
414
- cancelButton.classList.add('timepicker-close');
415
- cancelButton.addEventListener('click', this.close);
416
- confirmationBtnsContainer.appendChild(cancelButton);
417
-
418
- const doneButton = this._createButton(this.options.i18n.done, '');
419
- doneButton.classList.add('timepicker-close');
420
- doneButton.addEventListener('click', this.done);
421
- confirmationBtnsContainer.appendChild(doneButton);
422
- }
423
-
424
- _clockSetup() {
425
- if (this.options.twelveHour) {
426
- // AM Button
427
- this._amBtn = document.createElement('div');
428
- this._amBtn.classList.add('am-btn');
429
- this._amBtn.innerText = 'AM';
430
- this._amBtn.addEventListener('click', this._handleAmPmClick);
431
- this.spanAmPm.appendChild(this._amBtn);
432
- // PM Button
433
- this._pmBtn = document.createElement('div');
434
- this._pmBtn.classList.add('pm-btn');
435
- this._pmBtn.innerText = 'PM';
436
- this._pmBtn.addEventListener('click', this._handleAmPmClick);
437
- this.spanAmPm.appendChild(this._pmBtn);
438
- }
439
- this._buildHoursView();
440
- this._buildMinutesView();
441
- this._buildSVGClock();
442
- }
443
-
444
- _buildSVGClock() {
445
- // Draw clock hands and others
446
- let dialRadius = this.options.dialRadius;
447
- let tickRadius = this.options.tickRadius;
448
- let diameter = dialRadius * 2;
449
- let svg = Timepicker._createSVGEl('svg');
450
- svg.setAttribute('class', 'timepicker-svg');
451
- svg.setAttribute('width', diameter.toString());
452
- svg.setAttribute('height', diameter.toString());
453
- let g = Timepicker._createSVGEl('g');
454
- g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')');
455
- let bearing = Timepicker._createSVGEl('circle');
456
- bearing.setAttribute('class', 'timepicker-canvas-bearing');
457
- bearing.setAttribute('cx', '0');
458
- bearing.setAttribute('cy', '0');
459
- bearing.setAttribute('r', '4');
460
- let hand = Timepicker._createSVGEl('line');
461
- hand.setAttribute('x1', '0');
462
- hand.setAttribute('y1', '0');
463
- let bg = Timepicker._createSVGEl('circle');
464
- bg.setAttribute('class', 'timepicker-canvas-bg');
465
- bg.setAttribute('r', tickRadius.toString());
466
- g.appendChild(hand);
467
- g.appendChild(bg);
468
- g.appendChild(bearing);
469
- svg.appendChild(g);
470
- this._canvas.appendChild(svg);
471
- this.hand = hand;
472
- this.bg = bg;
473
- this.bearing = bearing;
474
- this.g = g;
475
- }
476
-
477
- _buildHoursView() {
478
- const $tick = document.createElement('div');
479
- $tick.classList.add('timepicker-tick');
480
- // Hours view
481
- if (this.options.twelveHour) {
482
- for (let i = 1; i < 13; i += 1) {
483
- const tick = <HTMLElement>$tick.cloneNode(true);
484
- const radian = (i / 6) * Math.PI;
485
- const radius = this.options.outerRadius;
486
- tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px';
487
- tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px';
488
- tick.innerHTML = i === 0 ? '00' : i.toString();
489
- this.hoursView.appendChild(tick);
490
- // tick.on(mousedownEvent, mousedown);
491
- }
492
- }
493
- else {
494
- for (let i = 0; i < 24; i += 1) {
495
- const tick = <HTMLElement>$tick.cloneNode(true);
496
- const radian = (i / 6) * Math.PI;
497
- const inner = i > 0 && i < 13;
498
- const radius = inner ? this.options.innerRadius : this.options.outerRadius;
499
- tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px';
500
- tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px';
501
- tick.innerHTML = i === 0 ? '00' : i.toString();
502
- this.hoursView.appendChild(tick);
503
- // tick.on(mousedownEvent, mousedown);
504
- }
505
- }
506
- }
507
-
508
- _buildMinutesView() {
509
- const _tick = document.createElement('div');
510
- _tick.classList.add('timepicker-tick');
511
- // Minutes view
512
- for (let i = 0; i < 60; i += 5) {
513
- const tick = <HTMLElement>_tick.cloneNode(true);
514
- const radian = (i / 30) * Math.PI;
515
- tick.style.left =
516
- this.options.dialRadius +
517
- Math.sin(radian) * this.options.outerRadius -
518
- this.options.tickRadius +
519
- 'px';
520
- tick.style.top =
521
- this.options.dialRadius -
522
- Math.cos(radian) * this.options.outerRadius -
523
- this.options.tickRadius +
524
- 'px';
525
- tick.innerHTML = Timepicker._addLeadingZero(i);
526
- this.minutesView.appendChild(tick);
527
- }
528
- }
529
-
530
- _handleAmPmClick = (e) => {
531
- const btnClicked = <HTMLElement>e.target;
532
- this.amOrPm = btnClicked.classList.contains('am-btn') ? 'AM' : 'PM';
533
- this._updateAmPmView();
534
- }
535
-
536
- _updateAmPmView() {
537
- if (this.options.twelveHour) {
538
- if (this.amOrPm === 'PM') {
539
- this._amBtn.classList.remove('text-primary');
540
- this._pmBtn.classList.add('text-primary');
541
- }
542
- else if (this.amOrPm === 'AM') {
543
- this._amBtn.classList.add('text-primary');
544
- this._pmBtn.classList.remove('text-primary');
545
- }
546
- }
547
- }
548
-
549
- _updateTimeFromInput() {
550
- // Get the time
551
- let value = ((this.el.value || this.options.defaultTime || '') + '').split(':');
552
- if (this.options.twelveHour && !(typeof value[1] === 'undefined')) {
553
- if (value[1].toUpperCase().indexOf('AM') > 0) {
554
- this.amOrPm = 'AM';
555
- } else {
556
- this.amOrPm = 'PM';
557
- }
558
- value[1] = value[1].replace('AM', '').replace('PM', '');
559
- }
560
- if (value[0] === 'now') {
561
- let now = new Date(+new Date() + this.options.fromNow);
562
- value = [now.getHours().toString(), now.getMinutes().toString()];
563
- if (this.options.twelveHour) {
564
- this.amOrPm = parseInt(value[0]) >= 12 && parseInt(value[0]) < 24 ? 'PM' : 'AM';
565
- }
566
- }
567
- this.hours = +value[0] || 0;
568
- this.minutes = +value[1] || 0;
569
- this.inputHours.value = this.hours;
570
- this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes);
571
-
572
- this._updateAmPmView();
573
- }
574
-
575
- /**
576
- * Show hours or minutes view on timepicker.
577
- * @param view The name of the view you want to switch to, 'hours' or 'minutes'.
578
- */
579
- showView = (view: Views, delay: number = null) => {
580
- if (view === 'minutes' && getComputedStyle(this.hoursView).visibility === 'visible') {
581
- // raiseCallback(this.options.beforeHourSelect);
582
- }
583
- let isHours = view === 'hours',
584
- nextView = isHours ? this.hoursView : this.minutesView,
585
- hideView = isHours ? this.minutesView : this.hoursView;
586
- this.currentView = view;
587
-
588
- if (isHours) {
589
- this.inputHours.classList.add('text-primary');
590
- this.inputMinutes.classList.remove('text-primary');
591
- }
592
- else {
593
- this.inputHours.classList.remove('text-primary');
594
- this.inputMinutes.classList.add('text-primary');
595
- }
596
-
597
- // Transition view
598
- hideView.classList.add('timepicker-dial-out');
599
-
600
- nextView.style.visibility = 'visible';
601
- nextView.classList.remove('timepicker-dial-out');
602
-
603
- // Reset clock hand
604
- this.resetClock(delay);
605
- // After transitions ended
606
- clearTimeout(this.toggleViewTimer);
607
- this.toggleViewTimer = setTimeout(() => {
608
- hideView.style.visibility = 'hidden';
609
- }, this.options.duration);
610
- }
611
-
612
- resetClock(delay) {
613
- let view = this.currentView,
614
- value = this[view],
615
- isHours = view === 'hours',
616
- unit = Math.PI / (isHours ? 6 : 30),
617
- radian = value * unit,
618
- radius =
619
- isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius,
620
- x = Math.sin(radian) * radius,
621
- y = -Math.cos(radian) * radius,
622
- self = this;
623
-
624
- if (delay) {
625
- this.canvas?.classList.add('timepicker-canvas-out');
626
- setTimeout(() => {
627
- self.canvas?.classList.remove('timepicker-canvas-out');
628
- self.setHand(x, y);
629
- }, delay);
630
- }
631
- else {
632
- this.setHand(x, y);
633
- }
634
- }
635
-
636
- _inputFromTextField = () => {
637
- const isHours = this.currentView === 'hours';
638
- if (isHours) {
639
- const value = parseInt(this.inputHours.value);
640
- if (value > 0 && value < 13) {
641
- this.drawClockFromTimeInput(value, isHours);
642
- this.showView('minutes', this.options.duration / 2);
643
- this.hours = value;
644
- this.inputMinutes.focus();
645
- }
646
- else {
647
- const hour = new Date().getHours();
648
- this.inputHours.value = (hour % 12).toString();
649
- }
650
- }
651
- else {
652
- const value = parseInt(this.inputMinutes.value);
653
- if (value >= 0 && value < 60) {
654
- this.inputMinutes.value = Timepicker._addLeadingZero(value);
655
- this.drawClockFromTimeInput(value, isHours);
656
- this.minutes = value;
657
- (<HTMLElement>this.modalEl.querySelector('.confirmation-btns :nth-child(2)')).focus();
658
- }
659
- else {
660
- const minutes = new Date().getMinutes();
661
- this.inputMinutes.value = Timepicker._addLeadingZero(minutes);
662
- }
663
- }
664
- }
665
-
666
- drawClockFromTimeInput(value, isHours) {
667
- const unit = Math.PI / (isHours ? 6 : 30);
668
- const radian = value * unit;
669
- let radius;
670
- if (this.options.twelveHour) {
671
- radius = this.options.outerRadius;
672
- }
673
- let cx1 = Math.sin(radian) * (radius - this.options.tickRadius),
674
- cy1 = -Math.cos(radian) * (radius - this.options.tickRadius),
675
- cx2 = Math.sin(radian) * radius,
676
- cy2 = -Math.cos(radian) * radius;
677
- this.hand.setAttribute('x2', cx1.toString());
678
- this.hand.setAttribute('y2', cy1.toString());
679
- this.bg.setAttribute('cx', cx2.toString());
680
- this.bg.setAttribute('cy', cy2.toString());
681
- }
682
-
683
- setHand(x, y, roundBy5: boolean = false) {
684
- let radian = Math.atan2(x, -y),
685
- isHours = this.currentView === 'hours',
686
- unit = Math.PI / (isHours || roundBy5 ? 6 : 30),
687
- z = Math.sqrt(x * x + y * y),
688
- inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2,
689
- radius = inner ? this.options.innerRadius : this.options.outerRadius;
690
-
691
- if (this.options.twelveHour) {
692
- radius = this.options.outerRadius;
693
- }
694
-
695
- // Radian should in range [0, 2PI]
696
- if (radian < 0) {
697
- radian = Math.PI * 2 + radian;
698
- }
699
-
700
- // Get the round value
701
- let value = Math.round(radian / unit);
702
-
703
- // Get the round radian
704
- radian = value * unit;
705
-
706
- // Correct the hours or minutes
707
- if (this.options.twelveHour) {
708
- if (isHours) {
709
- if (value === 0) value = 12;
710
- } else {
711
- if (roundBy5) value *= 5;
712
- if (value === 60) value = 0;
713
- }
714
- } else {
715
- if (isHours) {
716
- if (value === 12) {
717
- value = 0;
718
- }
719
- value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12;
720
- } else {
721
- if (roundBy5) {
722
- value *= 5;
723
- }
724
- if (value === 60) {
725
- value = 0;
726
- }
727
- }
728
- }
729
-
730
- // Once hours or minutes changed, vibrate the device
731
- if (this[this.currentView] !== value) {
732
- if (this.vibrate && this.options.vibrate) {
733
- // Do not vibrate too frequently
734
- if (!this.vibrateTimer) {
735
- navigator[this.vibrate](10);
736
- this.vibrateTimer = setTimeout(() => {
737
- this.vibrateTimer = null;
738
- }, 100);
739
- }
740
- }
741
- }
742
-
743
- this[this.currentView] = value;
744
- if (isHours) {
745
- this.inputHours.value = value.toString();
746
- }
747
- else {
748
- this.inputMinutes.value = Timepicker._addLeadingZero(value);
749
- }
750
-
751
- // Set clock hand and others' position
752
- let cx1 = Math.sin(radian) * (radius - this.options.tickRadius),
753
- cy1 = -Math.cos(radian) * (radius - this.options.tickRadius),
754
- cx2 = Math.sin(radian) * radius,
755
- cy2 = -Math.cos(radian) * radius;
756
- this.hand.setAttribute('x2', cx1.toString());
757
- this.hand.setAttribute('y2', cy1.toString());
758
- this.bg.setAttribute('cx', cx2.toString());
759
- this.bg.setAttribute('cy', cy2.toString());
760
- }
761
-
762
- /**
763
- * Open timepicker.
764
- */
765
- open = () => {
766
- if (this.isOpen) return;
767
- this.isOpen = true;
768
- this._updateTimeFromInput();
769
- this.showView('hours');
770
- this.modal.open(undefined);
771
- }
772
-
773
- /**
774
- * Close timepicker.
775
- */
776
- close = () => {
777
- if (!this.isOpen) return;
778
- this.isOpen = false;
779
- this.modal.close();
780
- }
781
-
782
- done = (e = null, clearValue = null) => {
783
- // Set input value
784
- let last = this.el.value;
785
- let value = clearValue
786
- ? ''
787
- : Timepicker._addLeadingZero(this.hours) + ':' + Timepicker._addLeadingZero(this.minutes);
788
- this.time = value;
789
- if (!clearValue && this.options.twelveHour) {
790
- value = `${value} ${this.amOrPm}`;
791
- }
792
- this.el.value = value;
793
- // Trigger change event
794
- if (value !== last) {
795
- this.el.dispatchEvent(new Event('change',{bubbles:true, cancelable:true, composed:true}));
796
- }
797
- this.close();
798
- this.el.focus();
799
- }
800
-
801
- clear = () => {
802
- this.done(null, true);
803
- }
804
-
805
- static {
806
- Timepicker._template = `
807
- <div class="modal timepicker-modal">
808
- <div class="modal-content timepicker-container">
809
- <div class="timepicker-digital-display">
810
- <div class="timepicker-text-container">
811
- <div class="timepicker-display-column">
812
- <input type="text" maxlength="2" autofocus class="timepicker-input-hours text-primary" />
813
- :
814
- <input type="text" maxlength="2" class="timepicker-input-minutes" />
815
- </div>
816
- <div class="timepicker-display-column timepicker-display-am-pm">
817
- <div class="timepicker-span-am-pm"></div>
818
- </div>
819
- </div>
820
- </div>
821
- <div class="timepicker-analog-display">
822
- <div class="timepicker-plate">
823
- <div class="timepicker-canvas"></div>
824
- <div class="timepicker-dial timepicker-hours"></div>
825
- <div class="timepicker-dial timepicker-minutes timepicker-dial-out"></div>
826
- </div>
827
- <div class="timepicker-footer"></div>
828
- </div>
829
- </div>
830
- </div`;
831
- }
832
- }