UNPKG

413 kBJavaScriptView Raw
1var CarbonComponents = (function (exports) {
2 'use strict';
3
4 /**
5 * Copyright IBM Corp. 2016, 2018
6 *
7 * This source code is licensed under the Apache-2.0 license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10
11 /**
12 * Settings.
13 * @exports CarbonComponents.settings
14 * @type Object
15 * @property {boolean} [disableAutoInit]
16 * Disables automatic instantiation of components.
17 * By default (`CarbonComponents.disableAutoInit` is `false`),
18 * carbon-components attempts to instantiate components automatically
19 * by searching for elements with `data-component-name` (e.g. `data-loading`) attribute
20 * or upon DOM events (e.g. clicking) on such elements.
21 * See each components' static `.init()` methods for details.
22 * @property {string} [prefix=bx]
23 * Brand prefix. Should be in sync with `$prefix` Sass variable in carbon-components/src/globals/scss/_vars.scss.
24 */
25 var settings = {
26 prefix: 'bx'
27 };
28 var settings_1 = settings;
29
30 function _classCallCheck(instance, Constructor) {
31 if (!(instance instanceof Constructor)) {
32 throw new TypeError("Cannot call a class as a function");
33 }
34 }
35
36 function _defineProperties(target, props) {
37 for (var i = 0; i < props.length; i++) {
38 var descriptor = props[i];
39 descriptor.enumerable = descriptor.enumerable || false;
40 descriptor.configurable = true;
41 if ("value" in descriptor) descriptor.writable = true;
42 Object.defineProperty(target, descriptor.key, descriptor);
43 }
44 }
45
46 function _createClass(Constructor, protoProps, staticProps) {
47 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
48 if (staticProps) _defineProperties(Constructor, staticProps);
49 return Constructor;
50 }
51
52 function _defineProperty(obj, key, value) {
53 if (key in obj) {
54 Object.defineProperty(obj, key, {
55 value: value,
56 enumerable: true,
57 configurable: true,
58 writable: true
59 });
60 } else {
61 obj[key] = value;
62 }
63
64 return obj;
65 }
66
67 function _objectSpread(target) {
68 for (var i = 1; i < arguments.length; i++) {
69 var source = arguments[i] != null ? arguments[i] : {};
70 var ownKeys = Object.keys(source);
71
72 if (typeof Object.getOwnPropertySymbols === 'function') {
73 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
74 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
75 }));
76 }
77
78 ownKeys.forEach(function (key) {
79 _defineProperty(target, key, source[key]);
80 });
81 }
82
83 return target;
84 }
85
86 function _inherits(subClass, superClass) {
87 if (typeof superClass !== "function" && superClass !== null) {
88 throw new TypeError("Super expression must either be null or a function");
89 }
90
91 subClass.prototype = Object.create(superClass && superClass.prototype, {
92 constructor: {
93 value: subClass,
94 writable: true,
95 configurable: true
96 }
97 });
98 if (superClass) _setPrototypeOf(subClass, superClass);
99 }
100
101 function _getPrototypeOf(o) {
102 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
103 return o.__proto__ || Object.getPrototypeOf(o);
104 };
105 return _getPrototypeOf(o);
106 }
107
108 function _setPrototypeOf(o, p) {
109 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
110 o.__proto__ = p;
111 return o;
112 };
113
114 return _setPrototypeOf(o, p);
115 }
116
117 function _assertThisInitialized(self) {
118 if (self === void 0) {
119 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
120 }
121
122 return self;
123 }
124
125 function _possibleConstructorReturn(self, call) {
126 if (call && (typeof call === "object" || typeof call === "function")) {
127 return call;
128 }
129
130 return _assertThisInitialized(self);
131 }
132
133 function _superPropBase(object, property) {
134 while (!Object.prototype.hasOwnProperty.call(object, property)) {
135 object = _getPrototypeOf(object);
136 if (object === null) break;
137 }
138
139 return object;
140 }
141
142 function _get(target, property, receiver) {
143 if (typeof Reflect !== "undefined" && Reflect.get) {
144 _get = Reflect.get;
145 } else {
146 _get = function _get(target, property, receiver) {
147 var base = _superPropBase(target, property);
148
149 if (!base) return;
150 var desc = Object.getOwnPropertyDescriptor(base, property);
151
152 if (desc.get) {
153 return desc.get.call(receiver);
154 }
155
156 return desc.value;
157 };
158 }
159
160 return _get(target, property, receiver || target);
161 }
162
163 function _slicedToArray(arr, i) {
164 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
165 }
166
167 function _toConsumableArray(arr) {
168 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
169 }
170
171 function _arrayWithoutHoles(arr) {
172 if (Array.isArray(arr)) {
173 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
174
175 return arr2;
176 }
177 }
178
179 function _arrayWithHoles(arr) {
180 if (Array.isArray(arr)) return arr;
181 }
182
183 function _iterableToArray(iter) {
184 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
185 }
186
187 function _iterableToArrayLimit(arr, i) {
188 var _arr = [];
189 var _n = true;
190 var _d = false;
191 var _e = undefined;
192
193 try {
194 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
195 _arr.push(_s.value);
196
197 if (i && _arr.length === i) break;
198 }
199 } catch (err) {
200 _d = true;
201 _e = err;
202 } finally {
203 try {
204 if (!_n && _i["return"] != null) _i["return"]();
205 } finally {
206 if (_d) throw _e;
207 }
208 }
209
210 return _arr;
211 }
212
213 function _nonIterableSpread() {
214 throw new TypeError("Invalid attempt to spread non-iterable instance");
215 }
216
217 function _nonIterableRest() {
218 throw new TypeError("Invalid attempt to destructure non-iterable instance");
219 }
220
221 /**
222 * Copyright IBM Corp. 2016, 2018
223 *
224 * This source code is licensed under the Apache-2.0 license found in the
225 * LICENSE file in the root directory of this source tree.
226 */
227
228 /**
229 * @param {Array} a An array.
230 * @returns {Array} The flattened version of the given array.
231 */
232 function flatten(a) {
233 return a.reduce(function (result, item) {
234 if (Array.isArray(item)) {
235 result.push.apply(result, _toConsumableArray(flatten(item)));
236 } else {
237 result.push(item);
238 }
239
240 return result;
241 }, []);
242 }
243 /**
244 * An interface for defining mix-in classes. Used with {@link mixin}.
245 * @function mixinfn
246 * @param {Class} ToMix The class to mix.
247 * @returns {Class} The class mixed-in with the given ToMix class.
248 */
249
250 /**
251 * @function mixin
252 * @param {...mixinfn} mixinfns The functions generating mix-ins.
253 * @returns {Class} The class generated with the given mix-ins.
254 */
255
256
257 function mixin() {
258 for (var _len = arguments.length, mixinfns = new Array(_len), _key = 0; _key < _len; _key++) {
259 mixinfns[_key] = arguments[_key];
260 }
261
262 return flatten(mixinfns).reduce(function (Class, mixinfn) {
263 return mixinfn(Class);
264 },
265 /*#__PURE__*/
266 function () {
267 function _class() {
268 _classCallCheck(this, _class);
269 }
270
271 return _class;
272 }());
273 }
274
275 /**
276 * Copyright IBM Corp. 2016, 2018
277 *
278 * This source code is licensed under the Apache-2.0 license found in the
279 * LICENSE file in the root directory of this source tree.
280 */
281 function createComponent (ToMix) {
282 var CreateComponent =
283 /*#__PURE__*/
284 function (_ToMix) {
285 _inherits(CreateComponent, _ToMix);
286
287 /**
288 * The component instances managed by this component.
289 * Releasing this component also releases the components in `this.children`.
290 * @type {Component[]}
291 */
292
293 /**
294 * Mix-in class to manage lifecycle of component.
295 * The constructor sets up this component's effective options,
296 * and registers this component't instance associated to an element.
297 * @implements Handle
298 * @param {HTMLElement} element The element working as this component.
299 * @param {Object} [options] The component options.
300 */
301 function CreateComponent(element) {
302 var _this;
303
304 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
305
306 _classCallCheck(this, CreateComponent);
307
308 _this = _possibleConstructorReturn(this, _getPrototypeOf(CreateComponent).call(this, element, options));
309
310 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "children", []);
311
312 if (!element || element.nodeType !== Node.ELEMENT_NODE) {
313 throw new TypeError('DOM element should be given to initialize this widget.');
314 }
315 /**
316 * The element the component is of.
317 * @type {Element}
318 */
319
320
321 _this.element = element;
322 /**
323 * The component options.
324 * @type {Object}
325 */
326
327 _this.options = Object.assign(Object.create(_this.constructor.options), options);
328
329 _this.constructor.components.set(_this.element, _assertThisInitialized(_assertThisInitialized(_this)));
330
331 return _this;
332 }
333 /**
334 * Instantiates this component of the given element.
335 * @param {HTMLElement} element The element.
336 */
337
338
339 _createClass(CreateComponent, [{
340 key: "release",
341
342 /**
343 * Releases this component's instance from the associated element.
344 */
345 value: function release() {
346 for (var child = this.children.pop(); child; child = this.children.pop()) {
347 child.release();
348 }
349
350 this.constructor.components.delete(this.element);
351 return null;
352 }
353 }], [{
354 key: "create",
355 value: function create(element, options) {
356 return this.components.get(element) || new this(element, options);
357 }
358 }]);
359
360 return CreateComponent;
361 }(ToMix);
362
363 return CreateComponent;
364 }
365
366 /**
367 * Copyright IBM Corp. 2016, 2018
368 *
369 * This source code is licensed under the Apache-2.0 license found in the
370 * LICENSE file in the root directory of this source tree.
371 */
372 function initComponentBySearch (ToMix) {
373 /**
374 * Mix-in class to instantiate components by searching for their root elements.
375 * @class InitComponentBySearch
376 */
377 var InitComponentBySearch =
378 /*#__PURE__*/
379 function (_ToMix) {
380 _inherits(InitComponentBySearch, _ToMix);
381
382 function InitComponentBySearch() {
383 _classCallCheck(this, InitComponentBySearch);
384
385 return _possibleConstructorReturn(this, _getPrototypeOf(InitComponentBySearch).apply(this, arguments));
386 }
387
388 _createClass(InitComponentBySearch, null, [{
389 key: "init",
390
391 /**
392 * Instantiates component in the given node.
393 * If the given element indicates that it's an component of this class, instantiates it.
394 * Otherwise, instantiates components by searching for components in the given node.
395 * @param {Node} target The DOM node to instantiate components in. Should be a document or an element.
396 * @param {Object} [options] The component options.
397 * @param {boolean} [options.selectorInit] The CSS selector to find components.
398 */
399 value: function init() {
400 var _this = this;
401
402 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
403 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
404 var effectiveOptions = Object.assign(Object.create(this.options), options);
405
406 if (!target || target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
407 throw new TypeError('DOM document or DOM element should be given to search for and initialize this widget.');
408 }
409
410 if (target.nodeType === Node.ELEMENT_NODE && target.matches(effectiveOptions.selectorInit)) {
411 this.create(target, options);
412 } else {
413 Array.prototype.forEach.call(target.querySelectorAll(effectiveOptions.selectorInit), function (element) {
414 return _this.create(element, options);
415 });
416 }
417 }
418 }]);
419
420 return InitComponentBySearch;
421 }(ToMix);
422
423 return InitComponentBySearch;
424 }
425
426 /**
427 * Copyright IBM Corp. 2016, 2018
428 *
429 * This source code is licensed under the Apache-2.0 license found in the
430 * LICENSE file in the root directory of this source tree.
431 */
432 function handles (ToMix) {
433 /**
434 * Mix-in class to manage handles in component.
435 * Managed handles are automatically released when the component with this class mixed in is released.
436 * @class Handles
437 * @implements Handle
438 */
439 var Handles =
440 /*#__PURE__*/
441 function (_ToMix) {
442 _inherits(Handles, _ToMix);
443
444 function Handles() {
445 var _getPrototypeOf2;
446
447 var _this;
448
449 _classCallCheck(this, Handles);
450
451 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
452 args[_key] = arguments[_key];
453 }
454
455 _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Handles)).call.apply(_getPrototypeOf2, [this].concat(args)));
456
457 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handles", new Set());
458
459 return _this;
460 }
461
462 _createClass(Handles, [{
463 key: "manage",
464
465 /**
466 * Manages the given handle.
467 * @param {Handle} handle The handle to manage.
468 * @returns {Handle} The given handle.
469 */
470 value: function manage(handle) {
471 this.handles.add(handle);
472 return handle;
473 }
474 /**
475 * Stop managing the given handle.
476 * @param {Handle} handle The handle to stop managing.
477 * @returns {Handle} The given handle.
478 */
479
480 }, {
481 key: "unmanage",
482 value: function unmanage(handle) {
483 this.handles.delete(handle);
484 return handle;
485 }
486 }, {
487 key: "release",
488 value: function release() {
489 var _this2 = this;
490
491 this.handles.forEach(function (handle) {
492 handle.release();
493
494 _this2.handles.delete(handle);
495 });
496 return _get(_getPrototypeOf(Handles.prototype), "release", this).call(this);
497 }
498 }]);
499
500 return Handles;
501 }(ToMix);
502
503 return Handles;
504 }
505
506 /**
507 * Copyright IBM Corp. 2016, 2018
508 *
509 * This source code is licensed under the Apache-2.0 license found in the
510 * LICENSE file in the root directory of this source tree.
511 */
512 function on(element) {
513 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
514 args[_key - 1] = arguments[_key];
515 }
516
517 element.addEventListener.apply(element, args);
518 return {
519 release: function release() {
520 element.removeEventListener.apply(element, args);
521 return null;
522 }
523 };
524 }
525
526 var stateChangeTypes = {
527 true: 'true',
528 false: 'false',
529 mixed: 'mixed'
530 };
531
532 var Checkbox =
533 /*#__PURE__*/
534 function (_mixin) {
535 _inherits(Checkbox, _mixin);
536
537 /**
538 * Checkbox UI.
539 * @extends CreateComponent
540 * @extends InitComponentBySearch
541 * @extends Handles
542 * @param {HTMLElement} element The element working as a checkbox UI.
543 */
544 function Checkbox(element, options) {
545 var _this;
546
547 _classCallCheck(this, Checkbox);
548
549 _this = _possibleConstructorReturn(this, _getPrototypeOf(Checkbox).call(this, element, options));
550
551 _this.manage(on(_this.element, 'click', function (event) {
552 _this._handleClick(event);
553 }));
554
555 _this.manage(on(_this.element, 'focus', function (event) {
556 _this._handleFocus(event);
557 }));
558
559 _this.manage(on(_this.element, 'blur', function (event) {
560 _this._handleBlur(event);
561 }));
562
563 _this._indeterminateCheckbox();
564
565 _this._initCheckbox();
566
567 return _this;
568 }
569
570 _createClass(Checkbox, [{
571 key: "_handleClick",
572 value: function _handleClick() {
573 if (this.element.checked === true) {
574 this.element.setAttribute('checked', '');
575 this.element.setAttribute('aria-checked', 'true');
576 this.element.checked = true; // nested checkboxes inside labels
577
578 if (this.element.parentElement.classList.contains(this.options.classLabel)) {
579 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxState, 'true');
580 }
581 } else if (this.element.checked === false) {
582 this.element.removeAttribute('checked');
583 this.element.setAttribute('aria-checked', 'false');
584 this.element.checked = false; // nested checkboxes inside labels
585
586 if (this.element.parentElement.classList.contains(this.options.classLabel)) {
587 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxState, 'false');
588 }
589 }
590 }
591 }, {
592 key: "_handleFocus",
593 value: function _handleFocus() {
594 if (this.element.parentElement.classList.contains(this.options.classLabel)) {
595 this.element.parentElement.classList.add(this.options.classLabelFocused);
596 }
597 }
598 }, {
599 key: "_handleBlur",
600 value: function _handleBlur() {
601 if (this.element.parentElement.classList.contains(this.options.classLabel)) {
602 this.element.parentElement.classList.remove(this.options.classLabelFocused);
603 }
604 }
605 /**
606 * Sets the new checkbox state.
607 * @param {boolean|string} [state]
608 * The new checkbox state to set. `mixed` to put checkbox in indeterminate state.
609 * If omitted, this method simply makes the style reflect `aria-checked` attribute.
610 */
611
612 }, {
613 key: "setState",
614 value: function setState(state) {
615 if (state === undefined || stateChangeTypes[state] === undefined) {
616 throw new TypeError('setState expects a value of true, false or mixed.');
617 }
618
619 this.element.setAttribute('aria-checked', state);
620 this.element.indeterminate = state === stateChangeTypes.mixed;
621 this.element.checked = state === stateChangeTypes.true;
622 var container = this.element.closest(this.options.selectorContainedCheckboxState);
623
624 if (container) {
625 container.setAttribute(this.options.attribContainedCheckboxState, state);
626 }
627 }
628 }, {
629 key: "setDisabled",
630 value: function setDisabled(value) {
631 if (value === undefined) {
632 throw new TypeError('setDisabled expects a boolean value of true or false');
633 }
634
635 if (value === true) {
636 this.element.setAttribute('disabled', true);
637 } else if (value === false) {
638 this.element.removeAttribute('disabled');
639 }
640
641 var container = this.element.closest(this.options.selectorContainedCheckboxDisabled);
642
643 if (container) {
644 container.setAttribute(this.options.attribContainedCheckboxDisabled, value);
645 }
646 }
647 }, {
648 key: "_indeterminateCheckbox",
649 value: function _indeterminateCheckbox() {
650 if (this.element.getAttribute('aria-checked') === 'mixed') {
651 this.element.indeterminate = true;
652 }
653
654 if (this.element.indeterminate === true) {
655 this.element.setAttribute('aria-checked', 'mixed');
656 }
657
658 if (this.element.parentElement.classList.contains(this.options.classLabel) && this.element.indeterminate === true) {
659 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxState, 'mixed');
660 }
661 }
662 }, {
663 key: "_initCheckbox",
664 value: function _initCheckbox() {
665 if (this.element.checked === true) {
666 this.element.setAttribute('aria-checked', 'true');
667 }
668
669 if (this.element.parentElement.classList.contains(this.options.classLabel) && this.element.checked) {
670 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxState, 'true');
671 }
672
673 if (this.element.parentElement.classList.contains(this.options.classLabel)) {
674 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxDisabled, 'false');
675 }
676
677 if (this.element.parentElement.classList.contains(this.options.classLabel) && this.element.disabled) {
678 this.element.parentElement.setAttribute(this.options.attribContainedCheckboxDisabled, 'true');
679 }
680 }
681 /**
682 * The map associating DOM element and copy button UI instance.
683 * @member Checkbox.components
684 * @type {WeakMap}
685 */
686
687 }], [{
688 key: "options",
689
690 /**
691 * The component options.
692 * If `options` is specified in the constructor, {@linkcode Checkbox.create .create()}, or {@linkcode Checkbox.init .init()},
693 * properties in this object are overriden for the instance being create and how {@linkcode Checkbox.init .init()} works.
694 * @member Checkbox.options
695 * @type {Object}
696 * @property {string} selectorInit The data attribute to find copy button UIs.
697 * @property {string} selectorContainedCheckboxState The CSS selector to find a container of checkbox preserving checked state.
698 * @property {string} selectorContainedCheckboxDisabled
699 * The CSS selector to find a container of checkbox preserving disabled state.
700 * @property {string} classLabel The CSS class for the label.
701 * @property {string} classLabelFocused The CSS class for the focused label.
702 * @property {string} attribContainedCheckboxState The attribute name for the checked state of contained checkbox.
703 * @property {string} attribContainedCheckboxDisabled The attribute name for the disabled state of contained checkbox.
704 */
705 get: function get() {
706 var prefix = settings_1.prefix;
707 return {
708 selectorInit: ".".concat(prefix, "--checkbox"),
709 selectorContainedCheckboxState: '[data-contained-checkbox-state]',
710 selectorContainedCheckboxDisabled: '[data-contained-checkbox-disabled]',
711 classLabel: "".concat(prefix, "--checkbox-label"),
712 classLabelFocused: "".concat(prefix, "--checkbox-label__focus"),
713 attribContainedCheckboxState: 'data-contained-checkbox-state',
714 attribContainedCheckboxDisabled: 'data-contained-checkbox-disabled'
715 };
716 }
717 }]);
718
719 return Checkbox;
720 }(mixin(createComponent, initComponentBySearch, handles));
721
722 _defineProperty(Checkbox, "components",
723 /* #__PURE_CLASS_PROPERTY__ */
724 new WeakMap());
725
726 _defineProperty(Checkbox, "stateChangeTypes",
727 /* #__PURE_CLASS_PROPERTY__ */
728 stateChangeTypes);
729
730 /**
731 * Copyright IBM Corp. 2016, 2018
732 *
733 * This source code is licensed under the Apache-2.0 license found in the
734 * LICENSE file in the root directory of this source tree.
735 */
736
737 /**
738 * Copyright IBM Corp. 2016, 2018
739 *
740 * This source code is licensed under the Apache-2.0 license found in the
741 * LICENSE file in the root directory of this source tree.
742 */
743 function eventedState (ToMix) {
744 /**
745 * Mix-in class to manage events associated with states.
746 * @class EventedState
747 */
748 var EventedState =
749 /*#__PURE__*/
750 function (_ToMix) {
751 _inherits(EventedState, _ToMix);
752
753 function EventedState() {
754 _classCallCheck(this, EventedState);
755
756 return _possibleConstructorReturn(this, _getPrototypeOf(EventedState).apply(this, arguments));
757 }
758
759 _createClass(EventedState, [{
760 key: "_changeState",
761 // eslint-disable-next-line jsdoc/check-param-names
762
763 /**
764 * The internal implementation for {@link EventedState#changeState `.changeState()`}, performing actual change in state.
765 * @param {string} [state] The new state. Can be an omitted, which means toggling.
766 * @param {Object} [detail]
767 * The object that should be put to event details that is fired before/after changing state.
768 * Can have a `group` property, which specifies what state to be changed.
769 * @param {EventedState~changeStateCallback} callback The callback called once changing state is finished or is canceled.
770 * @private
771 */
772 value: function _changeState() {
773 throw new Error('_changeState() should be overriden to perform actual change in state.');
774 } // eslint-disable-next-line jsdoc/check-param-names
775
776 /**
777 * Changes the state of this component.
778 * @param {string} [state] The new state. Can be an omitted, which means toggling.
779 * @param {Object} [detail]
780 * The object that should be put to event details that is fired before/after changing state.
781 * Can have a `group` property, which specifies what state to be changed.
782 * @param {EventedState~changeStateCallback} [callback] The callback called once changing state is finished or is canceled.
783 */
784
785 }, {
786 key: "changeState",
787 value: function changeState() {
788 var _this = this;
789
790 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
791 args[_key] = arguments[_key];
792 }
793
794 var state = typeof args[0] === 'string' ? args.shift() : undefined;
795 var detail = Object(args[0]) === args[0] && typeof args[0] !== 'function' ? args.shift() : undefined;
796 var callback = typeof args[0] === 'function' ? args.shift() : undefined;
797
798 if (typeof this.shouldStateBeChanged === 'function' && !this.shouldStateBeChanged(state, detail)) {
799 if (callback) {
800 callback(null, true);
801 }
802
803 return;
804 }
805
806 var data = {
807 group: detail && detail.group,
808 state: state
809 };
810 var eventNameSuffix = [data.group, state].filter(Boolean).join('-').split('-') // Group or state may contain hyphen
811 .map(function (item) {
812 return item[0].toUpperCase() + item.substr(1);
813 }).join('');
814 var eventStart = new CustomEvent(this.options["eventBefore".concat(eventNameSuffix)], {
815 bubbles: true,
816 cancelable: true,
817 detail: detail
818 });
819 var fireOnNode = detail && detail.delegatorNode || this.element;
820 var canceled = !fireOnNode.dispatchEvent(eventStart);
821
822 if (canceled) {
823 if (callback) {
824 var error = new Error("Changing state (".concat(JSON.stringify(data), ") has been canceled."));
825 error.canceled = true;
826 callback(error);
827 }
828 } else {
829 var changeStateArgs = [state, detail].filter(Boolean);
830
831 this._changeState.apply(this, _toConsumableArray(changeStateArgs).concat([function () {
832 fireOnNode.dispatchEvent(new CustomEvent(_this.options["eventAfter".concat(eventNameSuffix)], {
833 bubbles: true,
834 cancelable: true,
835 detail: detail
836 }));
837
838 if (callback) {
839 callback();
840 }
841 }]));
842 }
843 }
844 /**
845 * Tests if change in state should happen or not.
846 * Classes inheriting {@link EventedState `EventedState`} should override this function.
847 * @function EventedState#shouldStateBeChanged
848 * @param {string} [state] The new state. Can be an omitted, which means toggling.
849 * @param {Object} [detail]
850 * The object that should be put to event details that is fired before/after changing state.
851 * Can have a `group` property, which specifies what state to be changed.
852 * @returns {boolean}
853 * `false` if change in state shouldn't happen, e.g. when the given new state is the same as the current one.
854 */
855
856 }]);
857
858 return EventedState;
859 }(ToMix);
860 /**
861 * The callback called once changing state is finished or is canceled.
862 * @callback EventedState~changeStateCallback
863 * @param {Error} error
864 * An error object with `true` in its `canceled` property if changing state is canceled.
865 * Cancellation happens if the handler of a custom event, that is fired before changing state happens,
866 * calls `.preventDefault()` against the event.
867 * @param {boolean} keptState
868 * `true` if the call to {@link EventedState#changeState `.changeState()`} didn't cause actual change in state.
869 */
870
871
872 return EventedState;
873 }
874
875 /**
876 * Copyright IBM Corp. 2016, 2018
877 *
878 * This source code is licensed under the Apache-2.0 license found in the
879 * LICENSE file in the root directory of this source tree.
880 */
881
882 /**
883 * @param {Event} event The event.
884 * @param {string} selector The selector.
885 * @returns {Element}
886 * The closest ancestor of the event target (or the event target itself) which matches the selectors given in parameter.
887 */
888 function eventMatches(event, selector) {
889 // <svg> in IE does not have `Element#msMatchesSelector()` (that should be copied to `Element#matches()` by a polyfill).
890 // Also a weird behavior is seen in IE where DOM tree seems broken when `event.target` is on <svg>.
891 // Therefore this function simply returns `undefined` when `event.target` is on <svg>.
892 var target = event.target,
893 currentTarget = event.currentTarget;
894
895 if (typeof target.matches === 'function') {
896 if (target.matches(selector)) {
897 // If event target itself matches the given selector, return it
898 return target;
899 }
900
901 if (target.matches("".concat(selector, " *"))) {
902 var closest = target.closest(selector);
903
904 if ((currentTarget.nodeType === Node.DOCUMENT_NODE ? currentTarget.documentElement : currentTarget).contains(closest)) {
905 return closest;
906 }
907 }
908 }
909
910 return undefined;
911 }
912
913 var toArray = function toArray(arrayLike) {
914 return Array.prototype.slice.call(arrayLike);
915 };
916
917 var FileUploader =
918 /*#__PURE__*/
919 function (_mixin) {
920 _inherits(FileUploader, _mixin);
921
922 /**
923 * File uploader.
924 * @extends CreateComponent
925 * @extends InitComponentBySearch
926 * @extends eventedState
927 * @extends Handles
928 * @param {HTMLElement} element The element working as a file uploader.
929 * @param {Object} [options] The component options. See static options.
930 */
931 function FileUploader(element) {
932 var _this;
933
934 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
935
936 _classCallCheck(this, FileUploader);
937
938 _this = _possibleConstructorReturn(this, _getPrototypeOf(FileUploader).call(this, element, options));
939
940 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, detail, callback) {
941 if (state === 'delete-filename-fileuploader') {
942 _this.container.removeChild(detail.filenameElement);
943 }
944
945 if (typeof callback === 'function') {
946 callback();
947 }
948 });
949
950 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleDeleteButton", function (evt) {
951 var target = eventMatches(evt, "[data-for=".concat(_this.inputId, "]"));
952
953 if (target) {
954 _this._changeState('delete-filename-fileuploader', {
955 initialEvt: evt,
956 filenameElement: target.parentNode
957 });
958 }
959 });
960
961 _this.input = _this.element.querySelector(_this.options.selectorInput);
962 _this.container = _this.element.querySelector(_this.options.selectorContainer);
963
964 if (!_this.input) {
965 throw new TypeError('Cannot find the file input box.');
966 }
967
968 if (!_this.container) {
969 throw new TypeError('Cannot find the file names container.');
970 }
971
972 _this.inputId = _this.input.getAttribute('id');
973
974 _this.manage(on(_this.input, 'change', function () {
975 return _this._displayFilenames();
976 }));
977
978 _this.manage(on(_this.container, 'click', _this._handleDeleteButton));
979
980 return _this;
981 }
982
983 _createClass(FileUploader, [{
984 key: "_filenamesHTML",
985 value: function _filenamesHTML(name, id) {
986 return "<span class=\"".concat(this.options.classSelectedFile, "\">\n <p class=\"").concat(this.options.classFileName, "\">").concat(name, "</p>\n <span data-for=\"").concat(id, "\" class=\"").concat(this.options.classStateContainer, "\"></span>\n </span>");
987 }
988 }, {
989 key: "_uploadHTML",
990 value: function _uploadHTML() {
991 return "\n <div data-loading class=\"".concat(this.options.classLoading, "\">\n <svg class=\"").concat(this.options.classLoadingSvg, "\" viewBox=\"-42 -42 84 84\">\n <circle cx=\"0\" cy=\"0\" r=\"37.5\" />\n </svg>\n </div>");
992 }
993 }, {
994 key: "_closeButtonHTML",
995 value: function _closeButtonHTML() {
996 {
997 return "\n <button class=\"".concat(this.options.classFileClose, "\" type=\"button\" aria-label=\"close\">\n <svg aria-hidden=\"true\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">\n <path fill=\"#231F20\" d=\"M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8z\"/>\n </svg>\n </button>");
998 }
999
1000 return "\n <svg class=\"".concat(this.options.classFileClose, "\" tabindex=\"0\" viewBox=\"0 0 16 16\" fill-rule=\"evenodd\" width=\"16\" height=\"16\">\n <path d=\"M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3.5 10.1l-1.4 1.4L8\n 9.4l-2.1 2.1-1.4-1.4L6.6 8 4.5 5.9l1.4-1.4L8 6.6l2.1-2.1 1.4 1.4L9.4 8l2.1 2.1z\" />\n </svg>");
1001 }
1002 }, {
1003 key: "_checkmarkHTML",
1004 value: function _checkmarkHTML() {
1005 return "\n <svg class=\"".concat(this.options.classFileComplete, "\" viewBox=\"0 0 16 16\" fill-rule=\"evenodd\" width=\"16\" height=\"16\">\n <path d=\"M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zM6.7 11.5L3.4 8.1l1.4-1.4 1.9 1.9 4.1-4.1 1.4 1.4-5.5 5.6z\"/>\n </svg>");
1006 }
1007 }, {
1008 key: "_getStateContainers",
1009 value: function _getStateContainers() {
1010 var stateContainers = toArray(this.element.querySelectorAll("[data-for=".concat(this.inputId, "]")));
1011
1012 if (stateContainers.length === 0) {
1013 throw new TypeError('State container elements not found; invoke _displayFilenames() first');
1014 }
1015
1016 if (stateContainers[0].dataset.for !== this.inputId) {
1017 throw new TypeError('File input id must equal [data-for] attribute');
1018 }
1019
1020 return stateContainers;
1021 }
1022 /**
1023 * Inject selected files into DOM. Invoked on change event.
1024 */
1025
1026 }, {
1027 key: "_displayFilenames",
1028 value: function _displayFilenames() {
1029 var _this2 = this;
1030
1031 var container = this.element.querySelector(this.options.selectorContainer);
1032 var HTMLString = toArray(this.input.files).map(function (file) {
1033 return _this2._filenamesHTML(file.name, _this2.inputId);
1034 }).join('');
1035 container.insertAdjacentHTML('afterbegin', HTMLString);
1036 }
1037 }, {
1038 key: "_removeState",
1039 value: function _removeState(element) {
1040 if (!element || element.nodeType !== Node.ELEMENT_NODE) {
1041 throw new TypeError('DOM element should be given to initialize this widget.');
1042 }
1043
1044 while (element.firstChild) {
1045 element.removeChild(element.firstChild);
1046 }
1047 }
1048 }, {
1049 key: "_handleStateChange",
1050 value: function _handleStateChange(elements, selectIndex, html) {
1051 var _this3 = this;
1052
1053 if (selectIndex === undefined) {
1054 elements.forEach(function (el) {
1055 _this3._removeState(el);
1056
1057 el.insertAdjacentHTML('beforeend', html);
1058 });
1059 } else {
1060 elements.forEach(function (el, index) {
1061 if (index === selectIndex) {
1062 _this3._removeState(el);
1063
1064 el.insertAdjacentHTML('beforeend', html);
1065 }
1066 });
1067 }
1068 }
1069 /**
1070 * Handles delete button.
1071 * @param {Event} evt The event triggering this action.
1072 * @private
1073 */
1074
1075 }, {
1076 key: "setState",
1077 value: function setState(state, selectIndex) {
1078 var stateContainers = this._getStateContainers();
1079
1080 if (state === 'edit') {
1081 this._handleStateChange(stateContainers, selectIndex, this._closeButtonHTML());
1082 }
1083
1084 if (state === 'upload') {
1085 this._handleStateChange(stateContainers, selectIndex, this._uploadHTML());
1086 }
1087
1088 if (state === 'complete') {
1089 this._handleStateChange(stateContainers, selectIndex, this._checkmarkHTML());
1090 }
1091 }
1092 /**
1093 * The map associating DOM element and file uploader instance.
1094 * @member FileUploader.components
1095 * @type {WeakMap}
1096 */
1097
1098 }], [{
1099 key: "options",
1100 get: function get() {
1101 var prefix = settings_1.prefix;
1102 return {
1103 selectorInit: '[data-file]',
1104 selectorInput: "input[type=\"file\"].".concat(prefix, "--file-input"),
1105 selectorContainer: '[data-file-container]',
1106 selectorCloseButton: ".".concat(prefix, "--file-close"),
1107 classLoading: "".concat(prefix, "--loading"),
1108 classLoadingSvg: "".concat(prefix, "--loading__svg"),
1109 classFileName: "".concat(prefix, "--file-filename"),
1110 classFileClose: "".concat(prefix, "--file-close"),
1111 classFileComplete: "".concat(prefix, "--file-complete"),
1112 classSelectedFile: "".concat(prefix, "--file__selected-file"),
1113 classStateContainer: "".concat(prefix, "--file__state-container"),
1114 eventBeforeDeleteFilenameFileuploader: 'fileuploader-before-delete-filename',
1115 eventAfterDeleteFilenameFileuploader: 'fileuploader-after-delete-filename'
1116 };
1117 }
1118 }]);
1119
1120 return FileUploader;
1121 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
1122
1123 _defineProperty(FileUploader, "components",
1124 /* #__PURE_CLASS_PROPERTY__ */
1125 new WeakMap());
1126
1127 var toArray$1 = function toArray(arrayLike) {
1128 return Array.prototype.slice.call(arrayLike);
1129 };
1130
1131 var ContentSwitcher =
1132 /*#__PURE__*/
1133 function (_mixin) {
1134 _inherits(ContentSwitcher, _mixin);
1135
1136 /**
1137 * Set of content switcher buttons.
1138 * @extends CreateComponent
1139 * @extends InitComponentBySearch
1140 * @extends EventedState
1141 * @extends Handles
1142 * @param {HTMLElement} element The element working as a set of content switcher buttons.
1143 * @param {Object} [options] The component options.
1144 * @param {string} [options.selectorButton] The CSS selector to find switcher buttons.
1145 * @param {string} [options.selectorButtonSelected] The CSS selector to find the selected switcher button.
1146 * @param {string} [options.classActive] The CSS class for switcher button's selected state.
1147 * @param {string} [options.eventBeforeSelected]
1148 * The name of the custom event fired before a switcher button is selected.
1149 * Cancellation of this event stops selection of content switcher button.
1150 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a switcher button is selected.
1151 */
1152 function ContentSwitcher(element, options) {
1153 var _this;
1154
1155 _classCallCheck(this, ContentSwitcher);
1156
1157 _this = _possibleConstructorReturn(this, _getPrototypeOf(ContentSwitcher).call(this, element, options));
1158
1159 _this.manage(on(_this.element, 'click', function (event) {
1160 _this._handleClick(event);
1161 }));
1162
1163 return _this;
1164 }
1165 /**
1166 * Handles click on content switcher button set.
1167 * If the click is on a content switcher button, activates it.
1168 * @param {Event} event The event triggering this method.
1169 */
1170
1171
1172 _createClass(ContentSwitcher, [{
1173 key: "_handleClick",
1174 value: function _handleClick(event) {
1175 var button = eventMatches(event, this.options.selectorButton);
1176
1177 if (button) {
1178 this.changeState({
1179 group: 'selected',
1180 item: button,
1181 launchingEvent: event
1182 });
1183 }
1184 }
1185 /**
1186 * Internal method of {@linkcode ContentSwitcher#setActive .setActive()}, to select a content switcher button.
1187 * @private
1188 * @param {Object} detail The detail of the event trigging this action.
1189 * @param {HTMLElement} detail.item The button to be selected.
1190 * @param {Function} callback Callback called when change in state completes.
1191 */
1192
1193 }, {
1194 key: "_changeState",
1195 value: function _changeState(_ref, callback) {
1196 var _this2 = this;
1197
1198 var item = _ref.item;
1199 // `options.selectorLink` is not defined in this class itself, code here primary is for inherited classes
1200 var itemLink = item.querySelector(this.options.selectorLink);
1201
1202 if (itemLink) {
1203 toArray$1(this.element.querySelectorAll(this.options.selectorLink)).forEach(function (link) {
1204 if (link !== itemLink) {
1205 link.setAttribute('aria-selected', 'false');
1206 }
1207 });
1208 itemLink.setAttribute('aria-selected', 'true');
1209 }
1210
1211 var selectorButtons = toArray$1(this.element.querySelectorAll(this.options.selectorButton));
1212 selectorButtons.forEach(function (button) {
1213 if (button !== item) {
1214 button.setAttribute('aria-selected', false);
1215 button.classList.toggle(_this2.options.classActive, false);
1216 toArray$1(button.ownerDocument.querySelectorAll(button.dataset.target)).forEach(function (element) {
1217 element.setAttribute('hidden', '');
1218 element.setAttribute('aria-hidden', 'true');
1219 });
1220 }
1221 });
1222 item.classList.toggle(this.options.classActive, true);
1223 item.setAttribute('aria-selected', true);
1224 toArray$1(item.ownerDocument.querySelectorAll(item.dataset.target)).forEach(function (element) {
1225 element.removeAttribute('hidden');
1226 element.setAttribute('aria-hidden', 'false');
1227 });
1228
1229 if (callback) {
1230 callback();
1231 }
1232 }
1233 /**
1234 * Selects a content switcher button.
1235 * If the selected button has `data-target` attribute, DOM elements it points to as a CSS selector will be shown.
1236 * DOM elements associated with unselected buttons in the same way will be hidden.
1237 * @param {HTMLElement} item The button to be selected.
1238 * @param {ChangeState~callback} callback The callback is called once selection is finished
1239 * or is canceled. Will only invoke callback if it's passed in.
1240 */
1241
1242 }, {
1243 key: "setActive",
1244 value: function setActive(item, callback) {
1245 this.changeState({
1246 group: 'selected',
1247 item: item
1248 }, function (error) {
1249 if (error) {
1250 if (callback) {
1251 callback(Object.assign(error, {
1252 item: item
1253 }));
1254 }
1255 } else if (callback) {
1256 callback(null, item);
1257 }
1258 });
1259 }
1260 /**
1261 * The map associating DOM element and content switcher set instance.
1262 * @member ContentSwitcher.components
1263 * @type {WeakMap}
1264 */
1265
1266 }], [{
1267 key: "options",
1268
1269 /**
1270 * The component options.
1271 * If `options` is specified in the constructor,
1272 * {@linkcode ContentSwitcher.create .create()}, or {@linkcode ContentSwitcher.init .init()},
1273 * properties in this object are overriden for the instance being create and how {@linkcode ContentSwitcher.init .init()} works.
1274 * @member ContentSwitcher.options
1275 * @type {Object}
1276 * @property {string} selectorInit The CSS selector to find content switcher button set.
1277 * @property {string} [selectorButton] The CSS selector to find switcher buttons.
1278 * @property {string} [selectorButtonSelected] The CSS selector to find the selected switcher button.
1279 * @property {string} [classActive] The CSS class for switcher button's selected state.
1280 * @property {string} [eventBeforeSelected]
1281 * The name of the custom event fired before a switcher button is selected.
1282 * Cancellation of this event stops selection of content switcher button.
1283 * @property {string} [eventAfterSelected] The name of the custom event fired after a switcher button is selected.
1284 */
1285 get: function get() {
1286 var prefix = settings_1.prefix;
1287 return {
1288 selectorInit: '[data-content-switcher]',
1289 selectorButton: "input[type=\"radio\"], .".concat(prefix, "--content-switcher-btn"),
1290 classActive: "".concat(prefix, "--content-switcher--selected"),
1291 eventBeforeSelected: 'content-switcher-beingselected',
1292 eventAfterSelected: 'content-switcher-selected'
1293 };
1294 }
1295 }]);
1296
1297 return ContentSwitcher;
1298 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
1299
1300 _defineProperty(ContentSwitcher, "components",
1301 /* #__PURE_CLASS_PROPERTY__ */
1302 new WeakMap());
1303
1304 var toArray$2 = function toArray(arrayLike) {
1305 return Array.prototype.slice.call(arrayLike);
1306 };
1307
1308 var Tab =
1309 /*#__PURE__*/
1310 function (_ContentSwitcher) {
1311 _inherits(Tab, _ContentSwitcher);
1312
1313 /**
1314 * Container of tabs.
1315 * @extends ContentSwitcher
1316 * @param {HTMLElement} element The element working as a container of tabs.
1317 * @param {Object} [options] The component options.
1318 * @param {string} [options.selectorMenu] The CSS selector to find the drop down menu used in narrow mode.
1319 * @param {string} [options.selectorTrigger] The CSS selector to find the button to open the drop down menu used in narrow mode.
1320 * @param {string} [options.selectorTriggerText]
1321 * The CSS selector to find the element used in narrow mode showing the selected tab item.
1322 * @param {string} [options.selectorButton] The CSS selector to find tab containers.
1323 * @param {string} [options.selectorButtonSelected] The CSS selector to find the selected tab.
1324 * @param {string} [options.selectorLink] The CSS selector to find the links in tabs.
1325 * @param {string} [options.classActive] The CSS class for tab's selected state.
1326 * @param {string} [options.classHidden] The CSS class for the drop down menu's hidden state used in narrow mode.
1327 * @param {string} [options.eventBeforeSelected]
1328 * The name of the custom event fired before a tab is selected.
1329 * Cancellation of this event stops selection of tab.
1330 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a tab is selected.
1331 */
1332 function Tab(element, options) {
1333 var _this;
1334
1335 _classCallCheck(this, Tab);
1336
1337 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tab).call(this, element, options));
1338
1339 _this.manage(on(_this.element, 'keydown', function (event) {
1340 _this._handleKeyDown(event);
1341 }));
1342
1343 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
1344 _this._handleDocumentClick(event);
1345 }));
1346
1347 var selected = _this.element.querySelector(_this.options.selectorButtonSelected);
1348
1349 if (selected) {
1350 _this._updateTriggerText(selected);
1351 }
1352
1353 return _this;
1354 }
1355 /**
1356 * Internal method of {@linkcode Tab#setActive .setActive()}, to select a tab item.
1357 * @private
1358 * @param {Object} detail The detail of the event trigging this action.
1359 * @param {HTMLElement} detail.item The tab item to be selected.
1360 * @param {Function} callback Callback called when change in state completes.
1361 */
1362
1363
1364 _createClass(Tab, [{
1365 key: "_changeState",
1366 value: function _changeState(detail, callback) {
1367 var _this2 = this;
1368
1369 _get(_getPrototypeOf(Tab.prototype), "_changeState", this).call(this, detail, function (error) {
1370 if (!error) {
1371 _this2._updateTriggerText(detail.item);
1372 }
1373
1374 for (var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1375 data[_key - 1] = arguments[_key];
1376 }
1377
1378 callback.apply(void 0, [error].concat(data));
1379 });
1380 }
1381 /**
1382 * Handles click on tab container.
1383 * * If the click is on a tab, activates it.
1384 * * If the click is on the button to open the drop down menu, does so.
1385 * @param {Event} event The event triggering this method.
1386 */
1387
1388 }, {
1389 key: "_handleClick",
1390 value: function _handleClick(event) {
1391 var button = eventMatches(event, this.options.selectorButton);
1392 var trigger = eventMatches(event, this.options.selectorTrigger);
1393
1394 if (button && !button.classList.contains(this.options.classButtonDisabled)) {
1395 _get(_getPrototypeOf(Tab.prototype), "_handleClick", this).call(this, event);
1396
1397 this._updateMenuState(false);
1398 }
1399
1400 if (trigger) {
1401 this._updateMenuState();
1402 }
1403 }
1404 /**
1405 * Handles click on document.
1406 * @param {Event} event The triggering event.
1407 * @private
1408 */
1409
1410 }, {
1411 key: "_handleDocumentClick",
1412 value: function _handleDocumentClick(event) {
1413 var element = this.element;
1414 var isOfSelf = element.contains(event.target);
1415
1416 if (isOfSelf) {
1417 return;
1418 }
1419
1420 this._updateMenuState(false);
1421 }
1422 /**
1423 * Handles arrow keys on tab container.
1424 * * Left keys are used to go to previous tab.
1425 * * Right keys are used to go to next tab.
1426 * @param {Event} event The event triggering this method.
1427 */
1428
1429 }, {
1430 key: "_handleKeyDown",
1431 value: function _handleKeyDown(event) {
1432 var _this3 = this;
1433
1434 var triggerNode = eventMatches(event, this.options.selectorTrigger);
1435
1436 if (triggerNode) {
1437 if (event.which === 13) {
1438 this._updateMenuState();
1439 }
1440
1441 return;
1442 }
1443
1444 var direction = {
1445 37: this.constructor.NAVIGATE.BACKWARD,
1446 39: this.constructor.NAVIGATE.FORWARD
1447 }[event.which];
1448
1449 if (direction) {
1450 var buttons = toArray$2(this.element.querySelectorAll(this.options.selectorButtonEnabled));
1451 var button = this.element.querySelector(this.options.selectorButtonSelected);
1452 var nextIndex = Math.max(buttons.indexOf(button) + direction, -1
1453 /* For `button` not found in `buttons` */
1454 );
1455 var nextIndexLooped = nextIndex >= 0 && nextIndex < buttons.length ? nextIndex : nextIndex - Math.sign(nextIndex) * buttons.length;
1456 this.setActive(buttons[nextIndexLooped], function (error, item) {
1457 if (item) {
1458 var link = item.querySelector(_this3.options.selectorLink);
1459
1460 if (link) {
1461 link.focus();
1462 }
1463 }
1464 });
1465 event.preventDefault();
1466 }
1467 }
1468 /**
1469 * Shows/hides the drop down menu used in narrow mode.
1470 * @param {boolean} [force] `true` to show the menu, `false` to hide the menu, otherwise toggles the menu.
1471 */
1472
1473 }, {
1474 key: "_updateMenuState",
1475 value: function _updateMenuState(force) {
1476 var menu = this.element.querySelector(this.options.selectorMenu);
1477 var trigger = this.element.querySelector(this.options.selectorTrigger);
1478
1479 if (menu) {
1480 menu.classList.toggle(this.options.classHidden, typeof force === 'undefined' ? force : !force);
1481
1482 if (menu.classList.contains(this.options.classHidden)) {
1483 trigger.classList.remove(this.options.classOpen);
1484 } else {
1485 trigger.classList.add(this.options.classOpen);
1486 }
1487 }
1488 }
1489 /**
1490 * Updates the text indicating the currently selected tab item.
1491 * @param {HTMLElement} target The newly selected tab item.
1492 */
1493
1494 }, {
1495 key: "_updateTriggerText",
1496 value: function _updateTriggerText(target) {
1497 var triggerText = this.element.querySelector(this.options.selectorTriggerText);
1498
1499 if (triggerText) {
1500 triggerText.textContent = target.textContent;
1501 }
1502 }
1503 /**
1504 * The map associating DOM element and tab container instance.
1505 * @member Tab.components
1506 * @type {WeakMap}
1507 */
1508
1509 }], [{
1510 key: "options",
1511
1512 /**
1513 * The component options.
1514 * If `options` is specified in the constructor, {@linkcode ContentSwitcher.create .create()}, or {@linkcode Tab.init .init()},
1515 * properties in this object are overriden for the instance being create and how {@linkcode Tab.init .init()} works.
1516 * @member Tab.options
1517 * @type {Object}
1518 * @property {string} selectorInit The CSS selector to find tab containers.
1519 * @property {string} [selectorMenu] The CSS selector to find the drop down menu used in narrow mode.
1520 * @property {string} [selectorTrigger] The CSS selector to find the button to open the drop down menu used in narrow mode.
1521 * @property {string} [selectorTriggerText]
1522 * The CSS selector to find the element used in narrow mode showing the selected tab item.
1523 * @property {string} [selectorButton] The CSS selector to find tab containers.
1524 * @property {string} [selectorButtonSelected] The CSS selector to find the selected tab.
1525 * @property {string} [selectorLink] The CSS selector to find the links in tabs.
1526 * @property {string} [classActive] The CSS class for tab's selected state.
1527 * @property {string} [classHidden] The CSS class for the drop down menu's hidden state used in narrow mode.
1528 * @property {string} [eventBeforeSelected]
1529 * The name of the custom event fired before a tab is selected.
1530 * Cancellation of this event stops selection of tab.
1531 * @property {string} [eventAfterSelected] The name of the custom event fired after a tab is selected.
1532 */
1533 get: function get$$1() {
1534 var prefix = settings_1.prefix;
1535 return Object.assign(Object.create(ContentSwitcher.options), {
1536 selectorInit: '[data-tabs]',
1537 selectorMenu: ".".concat(prefix, "--tabs__nav"),
1538 selectorTrigger: ".".concat(prefix, "--tabs-trigger"),
1539 selectorTriggerText: ".".concat(prefix, "--tabs-trigger-text"),
1540 selectorButton: ".".concat(prefix, "--tabs__nav-item"),
1541 selectorButtonEnabled: ".".concat(prefix, "--tabs__nav-item:not(.").concat(prefix, "--tabs__nav-item--disabled)"),
1542 selectorButtonSelected: ".".concat(prefix, "--tabs__nav-item--selected"),
1543 selectorLink: ".".concat(prefix, "--tabs__nav-link"),
1544 classActive: "".concat(prefix, "--tabs__nav-item--selected"),
1545 classHidden: "".concat(prefix, "--tabs__nav--hidden"),
1546 classOpen: "".concat(prefix, "--tabs-trigger--open"),
1547 classButtonDisabled: "".concat(prefix, "--tabs__nav-item--disabled"),
1548 eventBeforeSelected: 'tab-beingselected',
1549 eventAfterSelected: 'tab-selected'
1550 });
1551 }
1552 /**
1553 * Enum for navigating backward/forward.
1554 * @readonly
1555 * @member Tab.NAVIGATE
1556 * @type {Object}
1557 * @property {number} BACKWARD Navigating backward.
1558 * @property {number} FORWARD Navigating forward.
1559 */
1560
1561 }]);
1562
1563 return Tab;
1564 }(ContentSwitcher);
1565
1566 _defineProperty(Tab, "components",
1567 /* #__PURE_CLASS_PROPERTY__ */
1568 new WeakMap());
1569
1570 _defineProperty(Tab, "NAVIGATE",
1571 /* #__PURE_CLASS_PROPERTY__ */
1572 {
1573 BACKWARD: -1,
1574 FORWARD: 1
1575 });
1576
1577 /**
1578 * Copyright IBM Corp. 2016, 2018
1579 *
1580 * This source code is licensed under the Apache-2.0 license found in the
1581 * LICENSE file in the root directory of this source tree.
1582 */
1583 function getLaunchingDetails(evt) {
1584 if (!evt || typeof evt === 'function') {
1585 return {
1586 launchingElement: null,
1587 launchingEvent: null
1588 };
1589 }
1590
1591 var launchingElement = evt.delegateTarget || evt.currentTarget || evt;
1592 var launchingEvent = evt.currentTarget && evt;
1593
1594 if (launchingElement && !launchingElement.nodeType) {
1595 throw new TypeError('DOM Node should be given for launching element.');
1596 }
1597
1598 if (launchingEvent && !launchingEvent.type) {
1599 throw new TypeError('DOM event should be given for launching event.');
1600 }
1601
1602 return {
1603 launchingElement: launchingElement,
1604 launchingEvent: launchingEvent
1605 };
1606 }
1607
1608 function eventedShowHideState(ToMix) {
1609 /**
1610 * Mix-in class to launch a floating menu.
1611 * @class EventedShowHideState
1612 */
1613 var EventedShowHideState =
1614 /*#__PURE__*/
1615 function (_ToMix) {
1616 _inherits(EventedShowHideState, _ToMix);
1617
1618 function EventedShowHideState() {
1619 _classCallCheck(this, EventedShowHideState);
1620
1621 return _possibleConstructorReturn(this, _getPrototypeOf(EventedShowHideState).apply(this, arguments));
1622 }
1623
1624 _createClass(EventedShowHideState, [{
1625 key: "show",
1626
1627 /**
1628 */
1629
1630 /**
1631 * Switch to 'shown' state.
1632 * @param [evtOrElem] The launching event or element.
1633 * @param {EventedState~changeStateCallback} [callback] The callback.
1634 */
1635 value: function show(evtOrElem, callback) {
1636 if (!evtOrElem || typeof evtOrElem === 'function') {
1637 callback = evtOrElem; // eslint-disable-line no-param-reassign
1638 }
1639
1640 this.changeState('shown', getLaunchingDetails(evtOrElem), callback);
1641 }
1642 /**
1643 * Switch to 'hidden' state.
1644 * @param [evtOrElem] The launching event or element.
1645 * @param {EventedState~changeStateCallback} [callback] The callback.
1646 */
1647
1648 }, {
1649 key: "hide",
1650 value: function hide(evtOrElem, callback) {
1651 if (!evtOrElem || typeof evtOrElem === 'function') {
1652 callback = evtOrElem; // eslint-disable-line no-param-reassign
1653 }
1654
1655 this.changeState('hidden', getLaunchingDetails(evtOrElem), callback);
1656 }
1657 }]);
1658
1659 return EventedShowHideState;
1660 }(ToMix);
1661
1662 return EventedShowHideState;
1663 }
1664
1665 var exports$1 = [eventedState, eventedShowHideState];
1666
1667 function trackBlur(ToMix) {
1668 var TrackBlur =
1669 /*#__PURE__*/
1670 function (_ToMix) {
1671 _inherits(TrackBlur, _ToMix);
1672
1673 /**
1674 * Mix-in class to add an handler for losing focus.
1675 * @extends Handles
1676 * @param {HTMLElement} element The element working as this component.
1677 * @param {Object} [options] The component options.
1678 */
1679 function TrackBlur(element, options) {
1680 var _this;
1681
1682 _classCallCheck(this, TrackBlur);
1683
1684 _this = _possibleConstructorReturn(this, _getPrototypeOf(TrackBlur).call(this, element, options));
1685 var hasFocusin = 'onfocusin' in window;
1686 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
1687
1688 _this.manage(on(_this.element.ownerDocument, focusinEventName, function (event) {
1689 if (!_this.element.contains(event.target)) {
1690 _this.handleBlur(event);
1691 }
1692 }, !hasFocusin));
1693
1694 return _this;
1695 }
1696 /**
1697 * The method called when this component loses focus.
1698 * @abstract
1699 */
1700
1701
1702 _createClass(TrackBlur, [{
1703 key: "handleBlur",
1704 value: function handleBlur() {
1705 throw new Error('Components inheriting TrackBlur mix-in must implement handleBlur() method.');
1706 }
1707 }]);
1708
1709 return TrackBlur;
1710 }(ToMix);
1711
1712 return TrackBlur;
1713 }
1714
1715 var exports$2 = [handles, trackBlur];
1716
1717 /**
1718 * Copyright IBM Corp. 2016, 2018
1719 *
1720 * This source code is licensed under the Apache-2.0 license found in the
1721 * LICENSE file in the root directory of this source tree.
1722 */
1723 // mdn resize function
1724 var optimizedResize =
1725 /* #__PURE__ */
1726 function optimizedResize() {
1727 var callbacks = [];
1728 var running = false; // run the actual callbacks
1729
1730 function runCallbacks() {
1731 callbacks.forEach(function (callback) {
1732 callback();
1733 });
1734 running = false;
1735 } // fired on resize event
1736
1737
1738 function resize() {
1739 if (!running) {
1740 running = true;
1741 window.requestAnimationFrame(runCallbacks);
1742 }
1743 } // adds callback to loop
1744
1745
1746 function addCallback(callback) {
1747 if (callback) {
1748 var index = callbacks.indexOf(callback);
1749
1750 if (index < 0) {
1751 callbacks.push(callback);
1752 }
1753 }
1754 }
1755
1756 return {
1757 // public method to add additional callback
1758 add: function add(callback) {
1759 if (!callbacks.length) {
1760 window.addEventListener('resize', resize);
1761 }
1762
1763 addCallback(callback);
1764 return {
1765 release: function release() {
1766 var index = callbacks.indexOf(callback);
1767
1768 if (index >= 0) {
1769 callbacks.splice(index, 1);
1770 }
1771 }
1772 };
1773 }
1774 };
1775 }();
1776
1777 /**
1778 * The structure for the position of floating menu.
1779 * @typedef {Object} FloatingMenu~position
1780 * @property {number} left The left position.
1781 * @property {number} top The top position.
1782 * @property {number} right The right position.
1783 * @property {number} bottom The bottom position.
1784 */
1785
1786 /**
1787 * The structure for the size of floating menu.
1788 * @typedef {Object} FloatingMenu~size
1789 * @property {number} width The width.
1790 * @property {number} height The height.
1791 */
1792
1793 /**
1794 * The structure for the position offset of floating menu.
1795 * @typedef {Object} FloatingMenu~offset
1796 * @property {number} top The top position.
1797 * @property {number} left The left position.
1798 */
1799
1800 var DIRECTION_LEFT = 'left';
1801 var DIRECTION_TOP = 'top';
1802 var DIRECTION_RIGHT = 'right';
1803 var DIRECTION_BOTTOM = 'bottom';
1804 /**
1805 * @param {Object} params The parameters.
1806 * @param {FloatingMenu~size} params.menuSize The size of the menu.
1807 * @param {FloatingMenu~position} params.refPosition The position of the triggering element.
1808 * @param {FloatingMenu~offset} [params.offset={ left: 0, top: 0 }] The position offset of the menu.
1809 * @param {string} [params.direction=bottom] The menu direction.
1810 * @param {number} [params.scrollX=0] The scroll position of the viewport.
1811 * @param {number} [params.scrollY=0] The scroll position of the viewport.
1812 * @returns {FloatingMenu~offset} The position of the menu, relative to the top-left corner of the viewport.
1813 * @private
1814 */
1815
1816 var getFloatingPosition = function getFloatingPosition(_ref) {
1817 var _DIRECTION_LEFT$DIREC;
1818
1819 var menuSize = _ref.menuSize,
1820 refPosition = _ref.refPosition,
1821 _ref$offset = _ref.offset,
1822 offset = _ref$offset === void 0 ? {} : _ref$offset,
1823 _ref$direction = _ref.direction,
1824 direction = _ref$direction === void 0 ? DIRECTION_BOTTOM : _ref$direction,
1825 _ref$scrollX = _ref.scrollX,
1826 scrollX = _ref$scrollX === void 0 ? 0 : _ref$scrollX,
1827 _ref$scrollY = _ref.scrollY,
1828 scrollY = _ref$scrollY === void 0 ? 0 : _ref$scrollY;
1829 var _refPosition$left = refPosition.left,
1830 refLeft = _refPosition$left === void 0 ? 0 : _refPosition$left,
1831 _refPosition$top = refPosition.top,
1832 refTop = _refPosition$top === void 0 ? 0 : _refPosition$top,
1833 _refPosition$right = refPosition.right,
1834 refRight = _refPosition$right === void 0 ? 0 : _refPosition$right,
1835 _refPosition$bottom = refPosition.bottom,
1836 refBottom = _refPosition$bottom === void 0 ? 0 : _refPosition$bottom;
1837 var width = menuSize.width,
1838 height = menuSize.height;
1839 var _offset$top = offset.top,
1840 top = _offset$top === void 0 ? 0 : _offset$top,
1841 _offset$left = offset.left,
1842 left = _offset$left === void 0 ? 0 : _offset$left;
1843 var refCenterHorizontal = (refLeft + refRight) / 2;
1844 var refCenterVertical = (refTop + refBottom) / 2;
1845 return (_DIRECTION_LEFT$DIREC = {}, _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_LEFT, {
1846 left: refLeft - width + scrollX - left,
1847 top: refCenterVertical - height / 2 + scrollY + top
1848 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_TOP, {
1849 left: refCenterHorizontal - width / 2 + scrollX + left,
1850 top: refTop - height + scrollY - top
1851 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_RIGHT, {
1852 left: refRight + scrollX + left,
1853 top: refCenterVertical - height / 2 + scrollY + top
1854 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_BOTTOM, {
1855 left: refCenterHorizontal - width / 2 + scrollX + left,
1856 top: refBottom + scrollY + top
1857 }), _DIRECTION_LEFT$DIREC)[direction];
1858 };
1859
1860 var FloatingMenu =
1861 /*#__PURE__*/
1862 function (_mixin) {
1863 _inherits(FloatingMenu, _mixin);
1864
1865 /**
1866 * Floating menu.
1867 * @extends CreateComponent
1868 * @extends EventedShowHideState
1869 * @param {HTMLElement} element The element working as a modal dialog.
1870 * @param {Object} [options] The component options.
1871 * @param {string} [options.selectorContainer] The CSS selector to find the container to put this menu in.
1872 * @param {string} [options.attribDirection] The attribute name to specify menu placement direction (top/right/bottom/left).
1873 * @param {string} [options.classShown] The CSS class for shown state, for the menu.
1874 * @param {string} [options.classRefShown] The CSS class for shown state, for the trigger button.
1875 * @param {string} [options.eventBeforeShown]
1876 * The name of the custom event fired before this menu is shown.
1877 * Cancellation of this event stops hiding the menu.
1878 * @param {string} [options.eventAfterShown]
1879 * The name of the custom event telling that menu is sure shown
1880 * without being canceled by the event handler named by `eventBeforeShown` option (`floating-menu-beingshown`).
1881 * @param {string} [options.eventBeforeHidden]
1882 * The name of the custom event fired before this menu is hidden.
1883 * Cancellation of this event stops hiding the menu.
1884 * @param {string} [options.eventAfterHidden]
1885 * The name of the custom event telling that menu is sure hidden
1886 * without being canceled by the event handler named by `eventBeforeHidden` option (`floating-menu-beinghidden`).
1887 * @param {Element} [options.refNode] The launching element of the menu. Used for calculating the geometry of the menu.
1888 * @param {Object} [options.offset] The offset to adjust the geometry of the menu. Should have `top`/`left` properties.
1889 */
1890 function FloatingMenu(element, options) {
1891 var _this;
1892
1893 _classCallCheck(this, FloatingMenu);
1894
1895 _this = _possibleConstructorReturn(this, _getPrototypeOf(FloatingMenu).call(this, element, options));
1896
1897 var attribDirectionValue = _this.element.getAttribute(_this.options.attribDirection);
1898
1899 if (!_this.options.direction) {
1900 _this.options.direction = attribDirectionValue || 'bottom';
1901 }
1902
1903 if (!attribDirectionValue) {
1904 // Update attribute for styling
1905 _this.element.setAttribute(_this.options.attribDirection, _this.options.direction);
1906 }
1907
1908 return _this;
1909 }
1910 /**
1911 * Focuses back on the trigger button if this component loses focus.
1912 */
1913
1914
1915 _createClass(FloatingMenu, [{
1916 key: "handleBlur",
1917 value: function handleBlur(event) {
1918 if (this.element.classList.contains(this.options.classShown)) {
1919 this.changeState('hidden', getLaunchingDetails(event));
1920 var refNode = this.options.refNode;
1921
1922 if (this.element.contains(event.relatedTarget) && refNode && event.target !== refNode) {
1923 HTMLElement.prototype.focus.call(refNode); // SVGElement in IE11 does not have `.focus()` method
1924 }
1925 }
1926 }
1927 /**
1928 * @private
1929 * @returns {Element} The element that this menu should be placed to.
1930 */
1931
1932 }, {
1933 key: "_getContainer",
1934 value: function _getContainer() {
1935 return this.element.closest(this.options.selectorContainer) || this.element.ownerDocument.body;
1936 }
1937 /**
1938 * @private
1939 * @returns {Object} The menu position, with `top` and `left` properties.
1940 */
1941
1942 }, {
1943 key: "_getPos",
1944 value: function _getPos() {
1945 var element = this.element;
1946 var _this$options = this.options,
1947 refNode = _this$options.refNode,
1948 offset = _this$options.offset,
1949 direction = _this$options.direction;
1950
1951 if (!refNode) {
1952 throw new Error('Cannot find the refernce node for positioning floating menu.');
1953 }
1954
1955 return getFloatingPosition({
1956 menuSize: element.getBoundingClientRect(),
1957 refPosition: refNode.getBoundingClientRect(),
1958 offset: typeof offset !== 'function' ? offset : offset(element, direction, refNode),
1959 direction: direction,
1960 scrollX: refNode.ownerDocument.defaultView.pageXOffset,
1961 scrollY: refNode.ownerDocument.defaultView.pageYOffset
1962 });
1963 }
1964 /**
1965 * Sees if the computed style is what this floating menu expects.
1966 * @private
1967 */
1968
1969 }, {
1970 key: "_testStyles",
1971 value: function _testStyles() {
1972 if (!this.options.debugStyle) {
1973 return;
1974 }
1975
1976 var element = this.element;
1977 var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
1978 var styles = {
1979 position: 'absolute',
1980 right: 'auto',
1981 margin: 0
1982 };
1983 Object.keys(styles).forEach(function (key) {
1984 var expected = typeof styles[key] === 'number' ? parseFloat(styles[key]) : styles[key];
1985 var actual = computedStyle.getPropertyValue(key);
1986
1987 if (expected !== actual) {
1988 // eslint-disable-next-line no-console
1989 console.warn("Floating menu component expects ".concat(key, ": ").concat(styles[key], " style."));
1990 }
1991 });
1992 }
1993 /**
1994 * Places the menu.
1995 * @private
1996 */
1997
1998 }, {
1999 key: "_place",
2000 value: function _place() {
2001 var element = this.element;
2002
2003 var _this$_getPos = this._getPos(),
2004 left = _this$_getPos.left,
2005 top = _this$_getPos.top;
2006
2007 element.style.left = "".concat(left, "px");
2008 element.style.top = "".concat(top, "px");
2009
2010 this._testStyles();
2011 }
2012 /**
2013 * @param {string} state The new state.
2014 * @returns {boolean} `true` of the current state is different from the given new state.
2015 */
2016
2017 }, {
2018 key: "shouldStateBeChanged",
2019 value: function shouldStateBeChanged(state) {
2020 return (state === 'shown' || state === 'hidden') && state !== (this.element.classList.contains(this.options.classShown) ? 'shown' : 'hidden');
2021 }
2022 /**
2023 * Changes the shown/hidden state.
2024 * @private
2025 * @param {string} state The new state.
2026 * @param {Object} detail The detail of the event trigging this action.
2027 * @param {Function} callback Callback called when change in state completes.
2028 */
2029
2030 }, {
2031 key: "_changeState",
2032 value: function _changeState(state, detail, callback) {
2033 var _this2 = this;
2034
2035 var shown = state === 'shown';
2036 var _this$options2 = this.options,
2037 refNode = _this$options2.refNode,
2038 classShown = _this$options2.classShown,
2039 classRefShown = _this$options2.classRefShown;
2040
2041 if (!refNode) {
2042 throw new TypeError('Cannot find the refernce node for changing the style.');
2043 }
2044
2045 this.element.classList.toggle(classShown, shown);
2046
2047 if (classRefShown) {
2048 refNode.classList.toggle(classRefShown, shown);
2049 }
2050
2051 if (state === 'shown') {
2052 if (!this.hResize) {
2053 this.hResize = optimizedResize.add(function () {
2054 _this2._place();
2055 });
2056 }
2057
2058 this._getContainer().appendChild(this.element);
2059
2060 this._place(); // IE11 puts focus on elements with `.focus()`, even ones without `tabindex` attribute
2061
2062
2063 if (!this.element.hasAttribute(this.options.attribAvoidFocusOnOpen)) {
2064 (this.element.querySelector(this.options.selectorPrimaryFocus) || this.element).focus();
2065 }
2066 }
2067
2068 if (state === 'hidden' && this.hResize) {
2069 this.hResize.release();
2070 this.hResize = null;
2071 }
2072
2073 callback();
2074 }
2075 }, {
2076 key: "release",
2077 value: function release() {
2078 if (this.hResize) {
2079 this.hResize.release();
2080 this.hResize = null;
2081 }
2082
2083 _get(_getPrototypeOf(FloatingMenu.prototype), "release", this).call(this);
2084 }
2085 }]);
2086
2087 return FloatingMenu;
2088 }(mixin(createComponent, exports$1, exports$2));
2089
2090 _defineProperty(FloatingMenu, "options",
2091 /* #__PURE_CLASS_PROPERTY__ */
2092 {
2093 selectorContainer: '[data-floating-menu-container]',
2094 selectorPrimaryFocus: '[data-floating-menu-primary-focus]',
2095 attribDirection: 'data-floating-menu-direction',
2096 attribAvoidFocusOnOpen: 'data-avoid-focus-on-open',
2097 classShown: '',
2098 // Should be provided from options arg in constructor
2099 classRefShown: '',
2100 // Should be provided from options arg in constructor
2101 eventBeforeShown: 'floating-menu-beingshown',
2102 eventAfterShown: 'floating-menu-shown',
2103 eventBeforeHidden: 'floating-menu-beinghidden',
2104 eventAfterHidden: 'floating-menu-hidden',
2105 refNode: null,
2106 // Should be provided from options arg in constructor
2107 offset: {
2108 left: 0,
2109 top: 0
2110 }
2111 });
2112
2113 _defineProperty(FloatingMenu, "components",
2114 /* #__PURE_CLASS_PROPERTY__ */
2115 new WeakMap());
2116
2117 /**
2118 * The CSS property names of the arrow keyed by the floating menu direction.
2119 * @type {Object<string, string>}
2120 */
2121
2122 var triggerButtonPositionProps =
2123 /* #__PURE__ */
2124 function () {
2125 var _ref;
2126
2127 return _ref = {}, _defineProperty(_ref, DIRECTION_TOP, 'bottom'), _defineProperty(_ref, DIRECTION_BOTTOM, 'top'), _defineProperty(_ref, DIRECTION_LEFT, 'left'), _defineProperty(_ref, DIRECTION_RIGHT, 'right'), _ref;
2128 }();
2129 /**
2130 * Determines how the position of arrow should affect the floating menu position.
2131 * @type {Object<string, number>}
2132 */
2133
2134
2135 var triggerButtonPositionFactors =
2136 /* #__PURE__ */
2137 function () {
2138 var _ref2;
2139
2140 return _ref2 = {}, _defineProperty(_ref2, DIRECTION_TOP, -2), _defineProperty(_ref2, DIRECTION_BOTTOM, -1), _defineProperty(_ref2, DIRECTION_LEFT, -2), _defineProperty(_ref2, DIRECTION_RIGHT, -1), _ref2;
2141 }();
2142 /**
2143 * @param {Element} menuBody The menu body with the menu arrow.
2144 * @param {string} direction The floating menu direction.
2145 * @param {Element} trigger The trigger button.
2146 * @returns {FloatingMenu~offset} The adjustment of the floating menu position, upon the position of the menu arrow.
2147 * @private
2148 */
2149
2150
2151 var getMenuOffset = function getMenuOffset(menuBody, direction, trigger) {
2152 var triggerButtonPositionProp = triggerButtonPositionProps[direction];
2153 var triggerButtonPositionFactor = triggerButtonPositionFactors[direction];
2154
2155 if (!triggerButtonPositionProp || !triggerButtonPositionFactor) {
2156 console.warn('Wrong floating menu direction:', direction); // eslint-disable-line no-console
2157 }
2158
2159 var menuWidth = menuBody.offsetWidth;
2160 var menuHeight = menuBody.offsetHeight;
2161 var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
2162 var values = [triggerButtonPositionProp, 'left', 'width', 'height', 'border-top-width'].reduce(function (o, name) {
2163 return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
2164 }, {});
2165
2166 if (Object.keys(values).every(function (name) {
2167 return !isNaN(values[name]);
2168 })) {
2169 var left = values.left,
2170 width = values.width,
2171 height = values.height,
2172 borderTopWidth = values['border-top-width'];
2173 return {
2174 left: menuWidth / 2 - (left + Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2),
2175 top: Math.sqrt(Math.pow(borderTopWidth, 2) * 2) + triggerButtonPositionFactor * values[triggerButtonPositionProp]
2176 };
2177 }
2178
2179 {
2180 // eslint-disable-next-line no-use-before-define
2181 var menu = OverflowMenu.components.get(trigger);
2182
2183 if (!menu) {
2184 throw new TypeError('Overflow menu instance cannot be found.');
2185 }
2186
2187 var flip = menuBody.classList.contains(menu.options.classMenuFlip);
2188
2189 if (triggerButtonPositionProp === 'top' || triggerButtonPositionProp === 'bottom') {
2190 var triggerWidth = trigger.offsetWidth;
2191 return {
2192 left: (!flip ? 1 : -1) * (menuWidth / 2 - triggerWidth / 2),
2193 top: 0
2194 };
2195 }
2196
2197 if (triggerButtonPositionProp === 'left' || triggerButtonPositionProp === 'right') {
2198 var triggerHeight = trigger.offsetHeight;
2199 return {
2200 left: 0,
2201 top: (!flip ? 1 : -1) * (menuHeight / 2 - triggerHeight / 2)
2202 };
2203 }
2204 }
2205
2206 return undefined;
2207 };
2208
2209 var OverflowMenu =
2210 /*#__PURE__*/
2211 function (_mixin) {
2212 _inherits(OverflowMenu, _mixin);
2213
2214 /**
2215 * Overflow menu.
2216 * @extends CreateComponent
2217 * @extends InitComponentBySearch
2218 * @extends Handles
2219 * @param {HTMLElement} element The element working as a modal dialog.
2220 * @param {Object} [options] The component options.
2221 * @param {string} [options.selectorOptionMenu] The CSS selector to find the menu.
2222 * @param {string} [options.classShown] The CSS class for the shown state, for the trigger UI.
2223 * @param {string} [options.classMenuShown] The CSS class for the shown state, for the menu.
2224 * @param {string} [options.classMenuFlip] The CSS class for the flipped state of the menu.
2225 * @param {Object} [options.objMenuOffset] The offset locating the menu for the non-flipped state.
2226 * @param {Object} [options.objMenuOffsetFlip] The offset locating the menu for the flipped state.
2227 */
2228 function OverflowMenu(element, options) {
2229 var _this;
2230
2231 _classCallCheck(this, OverflowMenu);
2232
2233 _this = _possibleConstructorReturn(this, _getPrototypeOf(OverflowMenu).call(this, element, options));
2234
2235 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
2236 var focused = _this.element.ownerDocument.activeElement;
2237 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(_this.options.selectorItem) ? focused : null;
2238 });
2239
2240 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
2241 var items = _toConsumableArray(_this.element.ownerDocument.querySelectorAll(_this.options.selectorItem));
2242
2243 var start = _this.getCurrentNavigation() || _this.element.querySelector(_this.options.selectorItemSelected);
2244
2245 var getNextItem = function getNextItem(old) {
2246 var handleUnderflow = function handleUnderflow(index, length) {
2247 return index + (index >= 0 ? 0 : length);
2248 };
2249
2250 var handleOverflow = function handleOverflow(index, length) {
2251 return index - (index < length ? 0 : length);
2252 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
2253
2254
2255 var index = Math.max(items.indexOf(old) + direction, -1);
2256 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
2257 };
2258
2259 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
2260 if (!current.matches(_this.options.selectorItemHidden) && !current.parentNode.matches(_this.options.selectorItemHidden) && !current.matches(_this.options.selectorItemSelected)) {
2261 current.focus();
2262 break;
2263 }
2264 }
2265 });
2266
2267 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
2268 _this._handleDocumentClick(event);
2269
2270 _this.wasOpenBeforeClick = undefined;
2271 }));
2272
2273 _this.manage(on(_this.element.ownerDocument, 'keydown', function (event) {
2274 _this._handleKeyPress(event);
2275 }));
2276
2277 _this.manage(on(_this.element, 'mousedown', function () {
2278 _this.wasOpenBeforeClick = element.classList.contains(_this.options.classShown);
2279 }));
2280
2281 return _this;
2282 }
2283 /**
2284 * Changes the shown/hidden state.
2285 * @param {string} state The new state.
2286 * @param {Object} detail The detail of the event trigging this action.
2287 * @param {Function} callback Callback called when change in state completes.
2288 */
2289
2290
2291 _createClass(OverflowMenu, [{
2292 key: "changeState",
2293 value: function changeState(state, detail, callback) {
2294 if (state === 'hidden') {
2295 this.element.setAttribute('aria-expanded', 'false');
2296 } else {
2297 this.element.setAttribute('aria-expanded', 'true');
2298 }
2299
2300 if (!this.optionMenu) {
2301 var optionMenu = this.element.querySelector(this.options.selectorOptionMenu);
2302
2303 if (!optionMenu) {
2304 throw new Error('Cannot find the target menu.');
2305 } // Lazily create a component instance for menu
2306
2307
2308 this.optionMenu = FloatingMenu.create(optionMenu, {
2309 refNode: this.element,
2310 classShown: this.options.classMenuShown,
2311 classRefShown: this.options.classShown,
2312 offset: this.options.objMenuOffset
2313 });
2314 this.children.push(this.optionMenu);
2315 }
2316
2317 if (this.optionMenu.element.classList.contains(this.options.classMenuFlip)) {
2318 this.optionMenu.options.offset = this.options.objMenuOffsetFlip;
2319 } // Delegates the action of changing state to the menu.
2320 // (And thus the before/after shown/hidden events are fired from the menu)
2321
2322
2323 this.optionMenu.changeState(state, Object.assign(detail, {
2324 delegatorNode: this.element
2325 }), callback);
2326 }
2327 /**
2328 * Handles click on document.
2329 * @param {Event} event The triggering event.
2330 * @private
2331 */
2332
2333 }, {
2334 key: "_handleDocumentClick",
2335 value: function _handleDocumentClick(event) {
2336 var element = this.element,
2337 optionMenu = this.optionMenu,
2338 wasOpenBeforeClick = this.wasOpenBeforeClick;
2339 var isOfSelf = element.contains(event.target);
2340 var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
2341 var shouldBeOpen = isOfSelf && !wasOpenBeforeClick;
2342 var state = shouldBeOpen ? 'shown' : 'hidden';
2343
2344 if (isOfSelf) {
2345 if (element.tagName === 'A') {
2346 event.preventDefault();
2347 }
2348
2349 event.delegateTarget = element; // eslint-disable-line no-param-reassign
2350 }
2351
2352 if (!isOfMenu || eventMatches(event, this.options.selectorItem)) {
2353 this.changeState(state, getLaunchingDetails(event), function () {
2354 if (state === 'hidden' && isOfMenu) {
2355 element.focus();
2356 }
2357 });
2358 }
2359 }
2360 /**
2361 * Provides the element to move focus from
2362 * @returns {Element} Currently highlighted element.
2363 */
2364
2365 }, {
2366 key: "_handleKeyPress",
2367
2368 /**
2369 * Handles key press on document.
2370 * @param {Event} event The triggering event.
2371 * @private
2372 */
2373 value: function _handleKeyPress(event) {
2374 var key = event.which;
2375 var element = this.element,
2376 optionMenu = this.optionMenu,
2377 options = this.options;
2378 var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
2379 var isExpanded = this.element.classList.contains(this.options.classShown);
2380
2381 switch (key) {
2382 // Esc
2383 case 27:
2384 this.changeState('hidden', getLaunchingDetails(event), function () {
2385 if (isOfMenu) {
2386 element.focus();
2387 }
2388 });
2389 break;
2390 // Enter || Space bar
2391
2392 case 13:
2393 case 32:
2394 {
2395 if (!isExpanded && this.element.ownerDocument.activeElement !== this.element) {
2396 return;
2397 }
2398
2399 var isOfSelf = element.contains(event.target);
2400 var shouldBeOpen = isOfSelf && !element.classList.contains(options.classShown);
2401 var state = shouldBeOpen ? 'shown' : 'hidden';
2402
2403 if (isOfSelf) {
2404 event.delegateTarget = element; // eslint-disable-line no-param-reassign
2405
2406 event.preventDefault(); // prevent scrolling
2407
2408 this.changeState(state, getLaunchingDetails(event), function () {
2409 if (state === 'hidden' && isOfMenu) {
2410 element.focus();
2411 }
2412 });
2413 }
2414
2415 break;
2416 }
2417
2418 case 38: // up arrow
2419
2420 case 40:
2421 // down arrow
2422 {
2423 if (!isExpanded) {
2424 return;
2425 }
2426
2427 event.preventDefault(); // prevent scrolling
2428
2429 var direction = {
2430 38: -1,
2431 40: 1
2432 }[event.which];
2433 this.navigate(direction);
2434 }
2435 break;
2436
2437 default:
2438 break;
2439 }
2440 }
2441 }], [{
2442 key: "options",
2443 get: function get() {
2444 var prefix = settings_1.prefix;
2445 return {
2446 selectorInit: '[data-overflow-menu]',
2447 selectorOptionMenu: ".".concat(prefix, "--overflow-menu-options"),
2448 selectorItem: "\n .".concat(prefix, "--overflow-menu-options--open >\n .").concat(prefix, "--overflow-menu-options__option:not(.").concat(prefix, "--overflow-menu-options__option--disabled) >\n .").concat(prefix, "--overflow-menu-options__btn\n "),
2449 classShown: "".concat(prefix, "--overflow-menu--open"),
2450 classMenuShown: "".concat(prefix, "--overflow-menu-options--open"),
2451 classMenuFlip: "".concat(prefix, "--overflow-menu--flip"),
2452 objMenuOffset: getMenuOffset,
2453 objMenuOffsetFlip: getMenuOffset
2454 };
2455 }
2456 }]);
2457
2458 return OverflowMenu;
2459 }(mixin(createComponent, initComponentBySearch, exports$1, handles));
2460
2461 _defineProperty(OverflowMenu, "components",
2462 /* #__PURE_CLASS_PROPERTY__ */
2463 new WeakMap());
2464
2465 function initComponentByLauncher (ToMix) {
2466 /**
2467 * Mix-in class to instantiate components events on launcher button.
2468 * @class InitComponentByLauncher
2469 */
2470 var InitComponentByLauncher =
2471 /*#__PURE__*/
2472 function (_ToMix) {
2473 _inherits(InitComponentByLauncher, _ToMix);
2474
2475 function InitComponentByLauncher() {
2476 _classCallCheck(this, InitComponentByLauncher);
2477
2478 return _possibleConstructorReturn(this, _getPrototypeOf(InitComponentByLauncher).apply(this, arguments));
2479 }
2480
2481 _createClass(InitComponentByLauncher, null, [{
2482 key: "init",
2483
2484 /**
2485 * `true` suggests that this component is lazily initialized upon an action/event, etc.
2486 * @type {boolean}
2487 */
2488
2489 /**
2490 * Instantiates this component in the given element.
2491 * If the given element indicates that it's an component of this class, instantiates it.
2492 * Otherwise, instantiates this component by clicking on launcher buttons
2493 * (buttons with attribute that `options.attribInitTarget` points to) of this component in the given node.
2494 * @param {Node} target The DOM node to instantiate this component in. Should be a document or an element.
2495 * @param {Object} [options] The component options.
2496 * @param {string} [options.selectorInit] The CSS selector to find this component.
2497 * @param {string} [options.attribInitTarget] The attribute name in the launcher buttons to find target component.
2498 * @returns {Handle} The handle to remove the event listener to handle clicking.
2499 */
2500 value: function init() {
2501 var _this = this;
2502
2503 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
2504 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2505 var effectiveOptions = Object.assign(Object.create(this.options), options);
2506
2507 if (!target || target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
2508 throw new TypeError('DOM document or DOM element should be given to search for and initialize this widget.');
2509 }
2510
2511 if (target.nodeType === Node.ELEMENT_NODE && target.matches(effectiveOptions.selectorInit)) {
2512 this.create(target, options);
2513 } else {
2514 var handles = effectiveOptions.initEventNames.map(function (name) {
2515 return on(target, name, function (event) {
2516 var launcher = eventMatches(event, "[".concat(effectiveOptions.attribInitTarget, "]"));
2517
2518 if (launcher) {
2519 event.delegateTarget = launcher; // eslint-disable-line no-param-reassign
2520
2521 var elements = launcher.ownerDocument.querySelectorAll(launcher.getAttribute(effectiveOptions.attribInitTarget));
2522
2523 if (elements.length > 1) {
2524 throw new Error('Target widget must be unique.');
2525 }
2526
2527 if (elements.length === 1) {
2528 if (launcher.tagName === 'A') {
2529 event.preventDefault();
2530 }
2531
2532 var component = _this.create(elements[0], options);
2533
2534 if (typeof component.createdByLauncher === 'function') {
2535 component.createdByLauncher(event);
2536 }
2537 }
2538 }
2539 });
2540 });
2541 return {
2542 release: function release() {
2543 for (var handle = handles.pop(); handle; handle = handles.pop()) {
2544 handle.release();
2545 }
2546 }
2547 };
2548 }
2549
2550 return '';
2551 }
2552 }]);
2553
2554 return InitComponentByLauncher;
2555 }(ToMix);
2556
2557 _defineProperty(InitComponentByLauncher, "forLazyInit",
2558 /* #__PURE_CLASS_PROPERTY__ */
2559 true);
2560
2561 return InitComponentByLauncher;
2562 }
2563
2564 var Modal =
2565 /*#__PURE__*/
2566 function (_mixin) {
2567 _inherits(Modal, _mixin);
2568
2569 /**
2570 * Modal dialog.
2571 * @extends CreateComponent
2572 * @extends InitComponentByLauncher
2573 * @extends EventedShowHideState
2574 * @extends Handles
2575 * @param {HTMLElement} element The element working as a modal dialog.
2576 * @param {Object} [options] The component options.
2577 * @param {string} [options.classVisible] The CSS class for the visible state.
2578 * @param {string} [options.eventBeforeShown]
2579 * The name of the custom event fired before this modal is shown.
2580 * Cancellation of this event stops showing the modal.
2581 * @param {string} [options.eventAfterShown]
2582 * The name of the custom event telling that modal is sure shown
2583 * without being canceled by the event handler named by `eventBeforeShown` option (`modal-beingshown`).
2584 * @param {string} [options.eventBeforeHidden]
2585 * The name of the custom event fired before this modal is hidden.
2586 * Cancellation of this event stops hiding the modal.
2587 * @param {string} [options.eventAfterHidden]
2588 * The name of the custom event telling that modal is sure hidden
2589 * without being canceled by the event handler named by `eventBeforeHidden` option (`modal-beinghidden`).
2590 */
2591 function Modal(element, options) {
2592 var _this;
2593
2594 _classCallCheck(this, Modal);
2595
2596 _this = _possibleConstructorReturn(this, _getPrototypeOf(Modal).call(this, element, options));
2597
2598 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusinListener", void 0);
2599
2600 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeydownListener", void 0);
2601
2602 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusin", function (evt) {
2603 if (_this.element.classList.contains(_this.options.classVisible) && !_this.element.contains(evt.target) && _this.options.selectorsFloatingMenus.every(function (selector) {
2604 return !eventMatches(evt, selector);
2605 })) {
2606 _this.element.focus();
2607 }
2608 });
2609
2610 _this._hookCloseActions();
2611
2612 return _this;
2613 }
2614 /**
2615 * The handle for `focusin` event listener.
2616 * Used for "focus-wrap" feature.
2617 * @type {Handle}
2618 * @private
2619 */
2620
2621
2622 _createClass(Modal, [{
2623 key: "createdByLauncher",
2624
2625 /**
2626 * A method that runs when `.init()` is called from `initComponentByLauncher`.
2627 * @param {Event} evt The event fired on the launcher button.
2628 */
2629 value: function createdByLauncher(evt) {
2630 this.show(evt);
2631 }
2632 /**
2633 * Determines whether or not to emit events and callback function when `.changeState()` is called from `eventedState`.
2634 * @param {string} state The new state.
2635 * @returns {boolean} `true` if the given `state` is different from current state.
2636 */
2637
2638 }, {
2639 key: "shouldStateBeChanged",
2640 value: function shouldStateBeChanged(state) {
2641 if (state === 'shown') {
2642 return !this.element.classList.contains(this.options.classVisible);
2643 }
2644
2645 return this.element.classList.contains(this.options.classVisible);
2646 }
2647 /**
2648 * Changes the shown/hidden state.
2649 * @private
2650 * @param {string} state The new state.
2651 * @param {Object} detail The detail data to be included in the event that will be fired.
2652 * @param {Function} callback Callback called when change in state completes.
2653 */
2654
2655 }, {
2656 key: "_changeState",
2657 value: function _changeState(state, detail, callback) {
2658 var _this2 = this;
2659
2660 var handleTransitionEnd;
2661
2662 var transitionEnd = function transitionEnd() {
2663 if (handleTransitionEnd) {
2664 handleTransitionEnd = _this2.unmanage(handleTransitionEnd).release();
2665 }
2666
2667 if (state === 'shown' && _this2.element.offsetWidth > 0 && _this2.element.offsetHeight > 0) {
2668 (_this2.element.querySelector(_this2.options.selectorPrimaryFocus) || _this2.element).focus();
2669 }
2670
2671 callback();
2672 };
2673
2674 if (this._handleFocusinListener) {
2675 this._handleFocusinListener = this.unmanage(this._handleFocusinListener).release();
2676 }
2677
2678 if (state === 'shown') {
2679 var hasFocusin = 'onfocusin' in this.element.ownerDocument.defaultView;
2680 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
2681 this._handleFocusinListener = this.manage(on(this.element.ownerDocument, focusinEventName, this._handleFocusin, !hasFocusin));
2682 }
2683
2684 if (state === 'hidden') {
2685 this.element.classList.toggle(this.options.classVisible, false);
2686 } else if (state === 'shown') {
2687 this.element.classList.toggle(this.options.classVisible, true);
2688 }
2689
2690 handleTransitionEnd = this.manage(on(this.element, 'transitionend', transitionEnd));
2691 }
2692 }, {
2693 key: "_hookCloseActions",
2694 value: function _hookCloseActions() {
2695 var _this3 = this;
2696
2697 this.manage(on(this.element, 'click', function (evt) {
2698 var closeButton = eventMatches(evt, _this3.options.selectorModalClose);
2699
2700 if (closeButton) {
2701 evt.delegateTarget = closeButton; // eslint-disable-line no-param-reassign
2702 }
2703
2704 if (closeButton || evt.target === _this3.element) {
2705 _this3.hide(evt);
2706 }
2707 }));
2708
2709 if (this._handleKeydownListener) {
2710 this._handleKeydownListener = this.unmanage(this._handleKeydownListener).release();
2711 }
2712
2713 this._handleKeydownListener = this.manage(on(this.element.ownerDocument.body, 'keydown', function (evt) {
2714 if (evt.which === 27) {
2715 evt.stopPropagation();
2716
2717 _this3.hide(evt);
2718 }
2719 }));
2720 }
2721 /**
2722 * Handles `focusin` (or `focus` depending on browser support of `focusin`) event to do wrap-focus behavior.
2723 * @param {Event} evt The event.
2724 * @private
2725 */
2726
2727 }], [{
2728 key: "options",
2729
2730 /**
2731 * The component options.
2732 * If `options` is specified in the constructor, {@linkcode Modal.create .create()}, or {@linkcode Modal.init .init()},
2733 * properties in this object are overriden for the instance being create and how {@linkcode Modal.init .init()} works.
2734 * @member Modal.options
2735 * @type {Object}
2736 * @property {string} selectorInit The CSS class to find modal dialogs.
2737 * @property {string} [selectorModalClose] The selector to find elements that close the modal.
2738 * @property {string} [selectorPrimaryFocus] The CSS selector to determine the element to put focus when modal gets open.
2739 * @property {string} attribInitTarget The attribute name in the launcher buttons to find target modal dialogs.
2740 * @property {string[]} [selectorsFloatingMenu]
2741 * The CSS selectors of floating menus.
2742 * Used for detecting if focus-wrap behavior should be disabled temporarily.
2743 * @property {string} [classVisible] The CSS class for the visible state.
2744 * @property {string} [classNoScroll] The CSS class for hiding scroll bar in body element while modal is shown.
2745 * @property {string} [eventBeforeShown]
2746 * The name of the custom event fired before this modal is shown.
2747 * Cancellation of this event stops showing the modal.
2748 * @property {string} [eventAfterShown]
2749 * The name of the custom event telling that modal is sure shown
2750 * without being canceled by the event handler named by `eventBeforeShown` option (`modal-beingshown`).
2751 * @property {string} [eventBeforeHidden]
2752 * The name of the custom event fired before this modal is hidden.
2753 * Cancellation of this event stops hiding the modal.
2754 * @property {string} [eventAfterHidden]
2755 * The name of the custom event telling that modal is sure hidden
2756 * without being canceled by the event handler named by `eventBeforeHidden` option (`modal-beinghidden`).
2757 */
2758 get: function get() {
2759 var prefix = settings_1.prefix;
2760 return {
2761 selectorInit: '[data-modal]',
2762 selectorModalClose: '[data-modal-close]',
2763 selectorPrimaryFocus: '[data-modal-primary-focus]',
2764 selectorsFloatingMenus: [".".concat(prefix, "--overflow-menu-options"), ".".concat(prefix, "--tooltip"), '.flatpickr-calendar'],
2765 classVisible: 'is-visible',
2766 attribInitTarget: 'data-modal-target',
2767 initEventNames: ['click'],
2768 eventBeforeShown: 'modal-beingshown',
2769 eventAfterShown: 'modal-shown',
2770 eventBeforeHidden: 'modal-beinghidden',
2771 eventAfterHidden: 'modal-hidden'
2772 };
2773 }
2774 }]);
2775
2776 return Modal;
2777 }(mixin(createComponent, initComponentByLauncher, exports$1, handles));
2778
2779 _defineProperty(Modal, "components",
2780 /* #__PURE_CLASS_PROPERTY__ */
2781 new WeakMap());
2782
2783 var Loading =
2784 /*#__PURE__*/
2785 function (_mixin) {
2786 _inherits(Loading, _mixin);
2787
2788 /**
2789 * Spinner indicating loading state.
2790 * @extends CreateComponent
2791 * @extends InitComponentBySearch
2792 * @extends Handles
2793 * @param {HTMLElement} element The element working as a spinner.
2794 * @param {Object} [options] The component options.
2795 * @param {boolean} [options.active] `true` if this spinner should roll.
2796 */
2797 function Loading(element, options) {
2798 var _this;
2799
2800 _classCallCheck(this, Loading);
2801
2802 _this = _possibleConstructorReturn(this, _getPrototypeOf(Loading).call(this, element, options));
2803 _this.active = _this.options.active; // Initialize spinner
2804
2805 _this.set(_this.active);
2806
2807 return _this;
2808 }
2809 /**
2810 * Sets active/inactive state.
2811 * @param {boolean} active `true` if this spinner should roll.
2812 */
2813
2814
2815 _createClass(Loading, [{
2816 key: "set",
2817 value: function set(active) {
2818 if (typeof active !== 'boolean') {
2819 throw new TypeError('set expects a boolean.');
2820 }
2821
2822 this.active = active;
2823 this.element.classList.toggle(this.options.classLoadingStop, !this.active);
2824 /**
2825 * If overlay is the parentNode then toggle it too.
2826 */
2827
2828 var parentNode = this.element.parentNode;
2829
2830 if (parentNode && parentNode.classList.contains(this.options.classLoadingOverlay)) {
2831 parentNode.classList.toggle(this.options.classLoadingOverlayStop, !this.active);
2832 }
2833
2834 return this;
2835 }
2836 /**
2837 * Toggles active/inactive state.
2838 */
2839
2840 }, {
2841 key: "toggle",
2842 value: function toggle() {
2843 return this.set(!this.active);
2844 }
2845 /**
2846 * @returns {boolean} `true` if this spinner is rolling.
2847 */
2848
2849 }, {
2850 key: "isActive",
2851 value: function isActive() {
2852 return this.active;
2853 }
2854 /**
2855 * Sets state to inactive and deletes the loading element.
2856 */
2857
2858 }, {
2859 key: "end",
2860 value: function end() {
2861 var _this2 = this;
2862
2863 this.set(false);
2864 var handleAnimationEnd = this.manage(on(this.element, 'animationend', function (evt) {
2865 if (handleAnimationEnd) {
2866 handleAnimationEnd = _this2.unmanage(handleAnimationEnd).release();
2867 }
2868
2869 if (evt.animationName === 'rotate-end-p2') {
2870 _this2._deleteElement();
2871 }
2872 }));
2873 }
2874 /**
2875 * Delete component from the DOM.
2876 */
2877
2878 }, {
2879 key: "_deleteElement",
2880 value: function _deleteElement() {
2881 var parentNode = this.element.parentNode;
2882 parentNode.removeChild(this.element);
2883
2884 if (parentNode.classList.contains(this.options.selectorLoadingOverlay)) {
2885 parentNode.remove();
2886 }
2887 }
2888 /**
2889 * The map associating DOM element and spinner instance.
2890 * @member Loading.components
2891 * @type {WeakMap}
2892 */
2893
2894 }], [{
2895 key: "options",
2896
2897 /**
2898 * The component options.
2899 * If `options` is specified in the constructor, {@linkcode Loading.create .create()}, or {@linkcode Loading.init .init()},
2900 * properties in this object are overriden for the instance being create and how {@linkcode Loading.init .init()} works.
2901 * @member Loading.options
2902 * @type {Object}
2903 * @property {string} selectorInit The CSS selector to find spinners.
2904 */
2905 get: function get() {
2906 var prefix = settings_1.prefix;
2907 return {
2908 selectorInit: '[data-loading]',
2909 selectorLoadingOverlay: ".".concat(prefix, "--loading-overlay"),
2910 classLoadingOverlay: "".concat(prefix, "--loading-overlay"),
2911 classLoadingStop: "".concat(prefix, "--loading--stop"),
2912 classLoadingOverlayStop: "".concat(prefix, "--loading-overlay--stop"),
2913 active: true
2914 };
2915 }
2916 }]);
2917
2918 return Loading;
2919 }(mixin(createComponent, initComponentBySearch, handles));
2920
2921 _defineProperty(Loading, "components",
2922 /* #__PURE_CLASS_PROPERTY__ */
2923 new WeakMap());
2924
2925 /**
2926 * Copyright IBM Corp. 2016, 2018
2927 *
2928 * This source code is licensed under the Apache-2.0 license found in the
2929 * LICENSE file in the root directory of this source tree.
2930 */
2931
2932 /**
2933 * Toggles the given attribute of the given element.
2934 * @param {Element} elem The element.
2935 * @param {string} name The attribute name.
2936 * @param {boolean} add `true` to set the attribute.
2937 */
2938 function toggleAttribute(elem, name, add) {
2939 if (add) {
2940 elem.setAttribute(name, '');
2941 } else {
2942 elem.removeAttribute(name);
2943 }
2944 }
2945
2946 var InlineLoading =
2947 /*#__PURE__*/
2948 function (_mixin) {
2949 _inherits(InlineLoading, _mixin);
2950
2951 /**
2952 * Spinner indicating loading state.
2953 * @extends CreateComponent
2954 * @extends InitComponentBySearch
2955 * @extends Handles
2956 * @param {HTMLElement} element The element working as a spinner.
2957 * @param {Object} [options] The component options.
2958 * @param {string} [options.initialState] The initial state, should be `inactive`, `active` or `finished`.
2959 */
2960 function InlineLoading(element, options) {
2961 var _this;
2962
2963 _classCallCheck(this, InlineLoading);
2964
2965 _this = _possibleConstructorReturn(this, _getPrototypeOf(InlineLoading).call(this, element, options)); // Sets the initial state
2966
2967 var initialState = _this.options.initialState;
2968
2969 if (initialState) {
2970 _this.setState(initialState);
2971 }
2972
2973 return _this;
2974 }
2975 /**
2976 * Sets active/inactive state.
2977 * @param {string} state The new state, should be `inactive`, `active` or `finished`.
2978 */
2979
2980
2981 _createClass(InlineLoading, [{
2982 key: "setState",
2983 value: function setState(state) {
2984 var states = this.constructor.states;
2985 var values = Object.keys(states).map(function (key) {
2986 return states[key];
2987 });
2988
2989 if (values.indexOf(state) < 0) {
2990 throw new Error("One of the following value should be given as the state: ".concat(values.join(', ')));
2991 }
2992
2993 var elem = this.element;
2994 var _this$options = this.options,
2995 selectorSpinner = _this$options.selectorSpinner,
2996 selectorFinished = _this$options.selectorFinished,
2997 selectorTextActive = _this$options.selectorTextActive,
2998 selectorTextFinished = _this$options.selectorTextFinished;
2999 var spinner = elem.querySelector(selectorSpinner);
3000 var finished = elem.querySelector(selectorFinished);
3001 var textActive = elem.querySelector(selectorTextActive);
3002 var textFinished = elem.querySelector(selectorTextFinished);
3003
3004 if (spinner) {
3005 spinner.classList.toggle(this.options.classLoadingStop, state !== states.ACTIVE);
3006 toggleAttribute(spinner, 'hidden', state === states.FINISHED);
3007 }
3008
3009 if (finished) {
3010 toggleAttribute(finished, 'hidden', state !== states.FINISHED);
3011 }
3012
3013 if (textActive) {
3014 toggleAttribute(textActive, 'hidden', state !== states.ACTIVE);
3015 }
3016
3017 if (textFinished) {
3018 toggleAttribute(textFinished, 'hidden', state !== states.FINISHED);
3019 }
3020
3021 return this;
3022 }
3023 /**
3024 * The list of states.
3025 * @type {Object<string, string>}
3026 */
3027
3028 }], [{
3029 key: "options",
3030
3031 /**
3032 * The component options.
3033 * If `options` is specified in the constructor, {@linkcode InlineLoading.create .create()},
3034 * or {@linkcode InlineLoading.init .init()},
3035 * properties in this object are overriden for the instance being create and how {@linkcode InlineLoading.init .init()} works.
3036 * @member InlineLoading.options
3037 * @type {Object}
3038 * @property {string} selectorInit The CSS selector to find inline loading components.
3039 * @property {string} selectorSpinner The CSS selector to find the spinner.
3040 * @property {string} selectorFinished The CSS selector to find the "finished" icon.
3041 * @property {string} selectorTextActive The CSS selector to find the text describing the active state.
3042 * @property {string} selectorTextFinished The CSS selector to find the text describing the finished state.
3043 * @property {string} classLoadingStop The CSS class for spinner's stopped state.
3044 */
3045 get: function get() {
3046 var prefix = settings_1.prefix;
3047 return {
3048 selectorInit: '[data-inline-loading]',
3049 selectorSpinner: '[data-inline-loading-spinner]',
3050 selectorFinished: '[data-inline-loading-finished]',
3051 selectorTextActive: '[data-inline-loading-text-active]',
3052 selectorTextFinished: '[data-inline-loading-text-finished]',
3053 classLoadingStop: "".concat(prefix, "--loading--stop")
3054 };
3055 }
3056 }]);
3057
3058 return InlineLoading;
3059 }(mixin(createComponent, initComponentBySearch, handles));
3060
3061 _defineProperty(InlineLoading, "states",
3062 /* #__PURE_CLASS_PROPERTY__ */
3063 {
3064 INACTIVE: 'inactive',
3065 ACTIVE: 'active',
3066 FINISHED: 'finished'
3067 });
3068
3069 _defineProperty(InlineLoading, "components",
3070 /* #__PURE_CLASS_PROPERTY__ */
3071 new WeakMap());
3072
3073 var toArray$3 = function toArray(arrayLike) {
3074 return Array.prototype.slice.call(arrayLike);
3075 };
3076
3077 var Dropdown =
3078 /*#__PURE__*/
3079 function (_mixin) {
3080 _inherits(Dropdown, _mixin);
3081
3082 /**
3083 * A selector with drop downs.
3084 * @extends CreateComponent
3085 * @extends InitComponentBySearch
3086 * @extends TrackBlur
3087 * @param {HTMLElement} element The element working as a selector.
3088 * @param {Object} [options] The component options.
3089 * @param {string} [options.selectorItem] The CSS selector to find clickable areas in dropdown items.
3090 * @param {string} [options.selectorItemSelected] The CSS selector to find the clickable area in the selected dropdown item.
3091 * @param {string} [options.classSelected] The CSS class for the selected dropdown item.
3092 * @param {string} [options.classOpen] The CSS class for the open state.
3093 * @param {string} [options.classDisabled] The CSS class for the disabled state.
3094 * @param {string} [options.eventBeforeSelected]
3095 * The name of the custom event fired before a drop down item is selected.
3096 * Cancellation of this event stops selection of drop down item.
3097 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a drop down item is selected.
3098 */
3099 function Dropdown(element, options) {
3100 var _this;
3101
3102 _classCallCheck(this, Dropdown);
3103
3104 _this = _possibleConstructorReturn(this, _getPrototypeOf(Dropdown).call(this, element, options));
3105
3106 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
3107 _this._toggle(event);
3108 }));
3109
3110 _this.manage(on(_this.element, 'keydown', function (event) {
3111 _this._handleKeyDown(event);
3112 }));
3113
3114 _this.manage(on(_this.element, 'click', function (event) {
3115 var item = eventMatches(event, _this.options.selectorItem);
3116
3117 if (item) {
3118 _this.select(item);
3119 }
3120 }));
3121
3122 return _this;
3123 }
3124 /**
3125 * Handles keydown event.
3126 * @param {Event} event The event triggering this method.
3127 */
3128
3129
3130 _createClass(Dropdown, [{
3131 key: "_handleKeyDown",
3132 value: function _handleKeyDown(event) {
3133 var isOpen = this.element.classList.contains(this.options.classOpen);
3134 var direction = {
3135 38: this.constructor.NAVIGATE.BACKWARD,
3136 40: this.constructor.NAVIGATE.FORWARD
3137 }[event.which];
3138
3139 if (isOpen && direction !== undefined) {
3140 this.navigate(direction);
3141 event.preventDefault(); // Prevents up/down keys from scrolling container
3142 } else {
3143 this._toggle(event);
3144 }
3145 }
3146 /**
3147 * Opens and closes the dropdown menu.
3148 * @param {Event} [event] The event triggering this method.
3149 */
3150
3151 }, {
3152 key: "_toggle",
3153 value: function _toggle(event) {
3154 var _this2 = this;
3155
3156 var isDisabled = this.element.classList.contains(this.options.classDisabled);
3157
3158 if (isDisabled) {
3159 return;
3160 }
3161
3162 if ([13, 32, 40].indexOf(event.which) >= 0 && !event.target.matches(this.options.selectorItem) || event.which === 27 || event.type === 'click') {
3163 var isOpen = this.element.classList.contains(this.options.classOpen);
3164 var isOfSelf = this.element.contains(event.target);
3165 var actions = {
3166 add: isOfSelf && event.which === 40 && !isOpen,
3167 remove: (!isOfSelf || event.which === 27) && isOpen,
3168 toggle: isOfSelf && event.which !== 27 && event.which !== 40
3169 };
3170 Object.keys(actions).forEach(function (action) {
3171 if (actions[action]) {
3172 _this2.element.classList[action](_this2.options.classOpen);
3173
3174 _this2.element.focus();
3175 }
3176 });
3177 var listItems = toArray$3(this.element.querySelectorAll(this.options.selectorItem));
3178 listItems.forEach(function (item) {
3179 if (_this2.element.classList.contains(_this2.options.classOpen)) {
3180 item.tabIndex = 0;
3181 } else {
3182 item.tabIndex = -1;
3183 }
3184 });
3185 }
3186 }
3187 /**
3188 * @returns {Element} Currently highlighted element.
3189 */
3190
3191 }, {
3192 key: "getCurrentNavigation",
3193 value: function getCurrentNavigation() {
3194 var focused = this.element.ownerDocument.activeElement;
3195 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(this.options.selectorItem) ? focused : null;
3196 }
3197 /**
3198 * Moves up/down the focus.
3199 * @param {number} direction The direction of navigating.
3200 */
3201
3202 }, {
3203 key: "navigate",
3204 value: function navigate(direction) {
3205 var items = toArray$3(this.element.querySelectorAll(this.options.selectorItem));
3206 var start = this.getCurrentNavigation() || this.element.querySelector(this.options.selectorItemSelected);
3207
3208 var getNextItem = function getNextItem(old) {
3209 var handleUnderflow = function handleUnderflow(i, l) {
3210 return i + (i >= 0 ? 0 : l);
3211 };
3212
3213 var handleOverflow = function handleOverflow(i, l) {
3214 return i - (i < l ? 0 : l);
3215 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
3216
3217
3218 var index = Math.max(items.indexOf(old) + direction, -1);
3219 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
3220 };
3221
3222 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
3223 if (!current.matches(this.options.selectorItemHidden) && !current.parentNode.matches(this.options.selectorItemHidden) && !current.matches(this.options.selectorItemSelected)) {
3224 current.focus();
3225 break;
3226 }
3227 }
3228 }
3229 /**
3230 * Handles clicking on the dropdown options, doing the following:
3231 * * Change Dropdown text to selected option.
3232 * * Remove selected option from options when selected.
3233 * * Emit custom events.
3234 * @param {HTMLElement} itemToSelect The element to be activated.
3235 */
3236
3237 }, {
3238 key: "select",
3239 value: function select(itemToSelect) {
3240 var _this3 = this;
3241
3242 var eventStart = new CustomEvent(this.options.eventBeforeSelected, {
3243 bubbles: true,
3244 cancelable: true,
3245 detail: {
3246 item: itemToSelect
3247 }
3248 });
3249
3250 if (this.element.dispatchEvent(eventStart)) {
3251 if (this.element.dataset.dropdownType !== 'navigation') {
3252 var selectorText = this.element.dataset.dropdownType !== 'inline' ? this.options.selectorText : this.options.selectorTextInner;
3253 var text = this.element.querySelector(selectorText);
3254
3255 if (text) {
3256 text.innerHTML = itemToSelect.innerHTML;
3257 }
3258
3259 itemToSelect.classList.add(this.options.classSelected);
3260 }
3261
3262 this.element.dataset.value = itemToSelect.parentElement.dataset.value;
3263 toArray$3(this.element.querySelectorAll(this.options.selectorItemSelected)).forEach(function (item) {
3264 if (itemToSelect !== item) {
3265 item.classList.remove(_this3.options.classSelected);
3266 }
3267 });
3268 this.element.dispatchEvent(new CustomEvent(this.options.eventAfterSelected, {
3269 bubbles: true,
3270 cancelable: true,
3271 detail: {
3272 item: itemToSelect
3273 }
3274 }));
3275 }
3276 }
3277 /**
3278 * Closes the dropdown menu if this component loses focus.
3279 */
3280
3281 }, {
3282 key: "handleBlur",
3283 value: function handleBlur() {
3284 this.element.classList.remove(this.options.classOpen);
3285 }
3286 /**
3287 * The map associating DOM element and selector instance.
3288 * @member Dropdown.components
3289 * @type {WeakMap}
3290 */
3291
3292 }], [{
3293 key: "options",
3294
3295 /**
3296 * The component options.
3297 * If `options` is specified in the constructor, {@linkcode Dropdown.create .create()}, or {@linkcode Dropdown.init .init()},
3298 * properties in this object are overriden for the instance being create and how {@linkcode Dropdown.init .init()} works.
3299 * @member Dropdown.options
3300 * @type {Object}
3301 * @property {string} selectorInit The CSS selector to find selectors.
3302 * @property {string} [selectorText] The CSS selector to find the element showing the selected item.
3303 * @property {string} [selectorTextInner] The CSS selector to find the element showing the selected item, used for inline mode.
3304 * @property {string} [selectorItem] The CSS selector to find clickable areas in dropdown items.
3305 * @property {string} [selectorItemHidden]
3306 * The CSS selector to find hidden dropdown items.
3307 * Used to skip dropdown items for keyboard navigation.
3308 * @property {string} [selectorItemSelected] The CSS selector to find the clickable area in the selected dropdown item.
3309 * @property {string} [classSelected] The CSS class for the selected dropdown item.
3310 * @property {string} [classOpen] The CSS class for the open state.
3311 * @property {string} [classDisabled] The CSS class for the disabled state.
3312 * @property {string} [eventBeforeSelected]
3313 * The name of the custom event fired before a drop down item is selected.
3314 * Cancellation of this event stops selection of drop down item.
3315 * @property {string} [eventAfterSelected] The name of the custom event fired after a drop down item is selected.
3316 */
3317 get: function get() {
3318 var prefix = settings_1.prefix;
3319 return {
3320 selectorInit: '[data-dropdown]',
3321 selectorText: ".".concat(prefix, "--dropdown-text"),
3322 selectorTextInner: ".".concat(prefix, "--dropdown-text__inner"),
3323 selectorItem: ".".concat(prefix, "--dropdown-link"),
3324 selectorItemSelected: ".".concat(prefix, "--dropdown--selected"),
3325 selectorItemHidden: "[hidden],[aria-hidden=\"true\"]",
3326 classSelected: "".concat(prefix, "--dropdown--selected"),
3327 classOpen: "".concat(prefix, "--dropdown--open"),
3328 classDisabled: "".concat(prefix, "--dropdown--disabled"),
3329 eventBeforeSelected: 'dropdown-beingselected',
3330 eventAfterSelected: 'dropdown-selected'
3331 };
3332 }
3333 /**
3334 * Enum for navigating backward/forward.
3335 * @readonly
3336 * @member Dropdown.NAVIGATE
3337 * @type {Object}
3338 * @property {number} BACKWARD Navigating backward.
3339 * @property {number} FORWARD Navigating forward.
3340 */
3341
3342 }]);
3343
3344 return Dropdown;
3345 }(mixin(createComponent, initComponentBySearch, exports$2));
3346
3347 _defineProperty(Dropdown, "components",
3348 /* #__PURE_CLASS_PROPERTY__ */
3349 new WeakMap());
3350
3351 _defineProperty(Dropdown, "NAVIGATE",
3352 /* #__PURE_CLASS_PROPERTY__ */
3353 {
3354 BACKWARD: -1,
3355 FORWARD: 1
3356 });
3357
3358 var NumberInput =
3359 /*#__PURE__*/
3360 function (_mixin) {
3361 _inherits(NumberInput, _mixin);
3362
3363 /**
3364 * Number input UI.
3365 * @extends CreateComponent
3366 * @extends InitComponentBySearch
3367 * @extends Handles
3368 * @param {HTMLElement} element The element working as a number input UI.
3369 */
3370 function NumberInput(element, options) {
3371 var _this;
3372
3373 _classCallCheck(this, NumberInput);
3374
3375 _this = _possibleConstructorReturn(this, _getPrototypeOf(NumberInput).call(this, element, options)); // Broken DOM tree is seen with up/down arrows <svg> in IE, which breaks event delegation.
3376 // <svg> does not have `Element.classList` in IE11
3377
3378 _this.manage(on(_this.element.querySelector('.up-icon'), 'click', function (event) {
3379 _this._handleClick(event);
3380 }));
3381
3382 _this.manage(on(_this.element.querySelector('.down-icon'), 'click', function (event) {
3383 _this._handleClick(event);
3384 }));
3385
3386 return _this;
3387 }
3388 /**
3389 * Increase/decrease number by clicking on up/down icons.
3390 * @param {Event} event The event triggering this method.
3391 */
3392
3393
3394 _createClass(NumberInput, [{
3395 key: "_handleClick",
3396 value: function _handleClick(event) {
3397 var numberInput = this.element.querySelector(this.options.selectorInput);
3398 var target = event.currentTarget.getAttribute('class').split(' ');
3399
3400 if (target.indexOf('up-icon') >= 0) {
3401 ++numberInput.value;
3402 } else if (target.indexOf('down-icon') >= 0) {
3403 --numberInput.value;
3404 } // Programmatic change in value (including `stepUp()`/`stepDown()`) won't fire change event
3405
3406
3407 numberInput.dispatchEvent(new CustomEvent('change', {
3408 bubbles: true,
3409 cancelable: false
3410 }));
3411 }
3412 /**
3413 * The map associating DOM element and number input UI instance.
3414 * @member NumberInput.components
3415 * @type {WeakMap}
3416 */
3417
3418 }], [{
3419 key: "options",
3420
3421 /**
3422 * The component options.
3423 * If `options` is specified in the constructor,
3424 * {@linkcode NumberInput.create .create()}, or {@linkcode NumberInput.init .init()},
3425 * properties in this object are overriden for the instance being create and how {@linkcode NumberInput.init .init()} works.
3426 * @member NumberInput.options
3427 * @type {Object}
3428 * @property {string} selectorInit The CSS selector to find number input UIs.
3429 * @property {string} [selectorInput] The CSS selector to find the `<input>` element.
3430 */
3431 get: function get() {
3432 var prefix = settings_1.prefix;
3433 return {
3434 selectorInit: '[data-numberinput]',
3435 selectorInput: ".".concat(prefix, "--number input")
3436 };
3437 }
3438 }]);
3439
3440 return NumberInput;
3441 }(mixin(createComponent, initComponentBySearch, handles));
3442
3443 _defineProperty(NumberInput, "components",
3444 /* #__PURE_CLASS_PROPERTY__ */
3445 new WeakMap());
3446
3447 var toArray$4 = function toArray(arrayLike) {
3448 return Array.prototype.slice.call(arrayLike);
3449 };
3450
3451 var suffix = '';
3452
3453 var DataTableV2 =
3454 /*#__PURE__*/
3455 function (_mixin) {
3456 _inherits(DataTableV2, _mixin);
3457
3458 /**
3459 * Data Table
3460 * @extends CreateComponent
3461 * @extends InitComponentBySearch
3462 * @extends EventedState
3463 * @param {HTMLElement} element The root element of tables
3464 * @param {Object} [options] the... options
3465 * @param {string} [options.selectorInit] selector initialization
3466 * @param {string} [options.selectorExpandCells] css selector for expand
3467 * @param {string} [options.expandableRow] css selector for expand
3468 * @param {string} [options.selectorParentRows] css selector for rows housing expansion
3469 * @param {string} [options.selectorTableBody] root css for table body
3470 * @param {string} [options.eventTrigger] selector for event bubble capture points
3471 * @param {string} [options.eventParentContainer] used find the bubble container
3472 */
3473 function DataTableV2(_element, options) {
3474 var _this;
3475
3476 _classCallCheck(this, DataTableV2);
3477
3478 _this = _possibleConstructorReturn(this, _getPrototypeOf(DataTableV2).call(this, _element, options));
3479
3480 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_sortToggle", function (detail) {
3481 var element = detail.element,
3482 previousValue = detail.previousValue;
3483 toArray$4(_this.tableHeaders).forEach(function (header) {
3484 var sortEl = header.querySelector(_this.options.selectorTableSort);
3485
3486 if (sortEl !== null && sortEl !== element) {
3487 sortEl.classList.remove(_this.options.classTableSortActive);
3488 sortEl.classList.remove(_this.options.classTableSortAscending);
3489 }
3490 });
3491
3492 if (!previousValue) {
3493 element.dataset.previousValue = 'ascending';
3494 element.classList.add(_this.options.classTableSortActive);
3495 element.classList.add(_this.options.classTableSortAscending);
3496 } else if (previousValue === 'ascending') {
3497 element.dataset.previousValue = 'descending';
3498 element.classList.add(_this.options.classTableSortActive);
3499 element.classList.remove(_this.options.classTableSortAscending);
3500 } else if (previousValue === 'descending') {
3501 element.removeAttribute('data-previous-value');
3502 element.classList.remove(_this.options.classTableSortActive);
3503 element.classList.remove(_this.options.classTableSortAscending);
3504 }
3505 });
3506
3507 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_selectToggle", function (detail) {
3508 var element = detail.element;
3509 var checked = element.checked; // increment the count
3510
3511 _this.state.checkboxCount += checked ? 1 : -1;
3512 _this.countEl.textContent = _this.state.checkboxCount;
3513 var row = element.parentNode.parentNode;
3514 row.classList.toggle(_this.options.classTableSelected); // toggle on/off batch action bar
3515
3516 _this._actionBarToggle(_this.state.checkboxCount > 0);
3517 });
3518
3519 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_selectAllToggle", function (_ref) {
3520 var element = _ref.element;
3521 var checked = element.checked;
3522 var inputs = toArray$4(_this.element.querySelectorAll(_this.options.selectorCheckbox));
3523 _this.state.checkboxCount = checked ? inputs.length - 1 : 0;
3524 inputs.forEach(function (item) {
3525 item.checked = checked;
3526 var row = item.parentNode.parentNode;
3527
3528 if (checked && row) {
3529 row.classList.add(_this.options.classTableSelected);
3530 } else {
3531 row.classList.remove(_this.options.classTableSelected);
3532 }
3533 });
3534
3535 _this._actionBarToggle(_this.state.checkboxCount > 0);
3536
3537 if (_this.batchActionEl) {
3538 _this.countEl.textContent = _this.state.checkboxCount;
3539 }
3540 });
3541
3542 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_actionBarCancel", function () {
3543 var inputs = toArray$4(_this.element.querySelectorAll(_this.options.selectorCheckbox));
3544 var row = toArray$4(_this.element.querySelectorAll(_this.options.selectorTableSelected));
3545 row.forEach(function (item) {
3546 item.classList.remove(_this.options.classTableSelected);
3547 });
3548 inputs.forEach(function (item) {
3549 item.checked = false;
3550 });
3551 _this.state.checkboxCount = 0;
3552
3553 _this._actionBarToggle(false);
3554
3555 if (_this.batchActionEl) {
3556 _this.countEl.textContent = _this.state.checkboxCount;
3557 }
3558 });
3559
3560 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_actionBarToggle", function (toggleOn) {
3561 var transition = function transition(evt) {
3562 _this.batchActionEl.removeEventListener('transitionend', transition);
3563
3564 if (evt.target.matches(_this.options.selectorActions)) {
3565 if (_this.batchActionEl.dataset.active === 'false') {
3566 _this.batchActionEl.setAttribute('tabIndex', -1);
3567 } else {
3568 _this.batchActionEl.setAttribute('tabIndex', 0);
3569 }
3570 }
3571 };
3572
3573 if (toggleOn) {
3574 _this.batchActionEl.dataset.active = true;
3575
3576 _this.batchActionEl.classList.add(_this.options.classActionBarActive);
3577 } else if (_this.batchActionEl) {
3578 _this.batchActionEl.dataset.active = false;
3579
3580 _this.batchActionEl.classList.remove(_this.options.classActionBarActive);
3581 }
3582
3583 if (_this.batchActionEl) {
3584 _this.batchActionEl.addEventListener('transitionend', transition);
3585 }
3586 });
3587
3588 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_expandableRowsInit", function (expandableRows) {
3589 expandableRows.forEach(function (item) {
3590 });
3591 });
3592
3593 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_rowExpandToggle", function (_ref2) {
3594 var element = _ref2.element,
3595 initialEvt = _ref2.initialEvt;
3596 var parent = eventMatches(initialEvt, _this.options.eventParentContainer);
3597
3598 var index = _this.expandCells.indexOf(element);
3599
3600 if (element.dataset.previousValue === undefined || element.dataset.previousValue === 'expanded') {
3601 element.dataset.previousValue = 'collapsed';
3602 parent.classList.add(_this.options.classExpandableRow);
3603 } else {
3604 parent.classList.remove(_this.options.classExpandableRow);
3605
3606 element.dataset.previousValue = 'expanded';
3607 }
3608 });
3609
3610 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_expandableHoverToggle", function (element) {
3611 element.previousElementSibling.classList.add(_this.options.classExpandableRowHover);
3612
3613 var mouseout = function mouseout() {
3614 element.previousElementSibling.classList.remove(_this.options.classExpandableRowHover);
3615 element.removeEventListener('mouseout', mouseout);
3616 };
3617
3618 element.addEventListener('mouseout', mouseout);
3619 });
3620
3621 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleState", function (element, evt) {
3622 var data = element.dataset;
3623 var label = data.label ? data.label : '';
3624 var previousValue = data.previousValue ? data.previousValue : '';
3625 var initialEvt = evt;
3626
3627 _this.changeState({
3628 group: data.event,
3629 element: element,
3630 label: label,
3631 previousValue: previousValue,
3632 initialEvt: initialEvt
3633 });
3634 });
3635
3636 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_keydownHandler", function (evt) {
3637 var searchContainer = _this.element.querySelector(_this.options.selectorToolbarSearchContainer);
3638
3639 var searchEvent = eventMatches(evt, _this.options.selectorSearchMagnifier);
3640 var activeSearch = searchContainer.classList.contains(_this.options.classToolbarSearchActive);
3641
3642 if (evt.which === 27) {
3643 _this._actionBarCancel();
3644 }
3645
3646 if (searchContainer && searchEvent && evt.which === 13) {
3647 _this.activateSearch(searchContainer);
3648 }
3649
3650 if (activeSearch && evt.which === 27) {
3651 _this.deactivateSearch(searchContainer, evt);
3652 }
3653 });
3654
3655 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "refreshRows", function () {
3656 var newExpandCells = toArray$4(_this.element.querySelectorAll(_this.options.selectorExpandCells));
3657 var newExpandableRows = toArray$4(_this.element.querySelectorAll(_this.options.selectorExpandableRows));
3658 var newParentRows = toArray$4(_this.element.querySelectorAll(_this.options.selectorParentRows)); // check if this is a refresh or the first time
3659
3660 if (_this.parentRows.length > 0) {
3661 var diffParentRows = newParentRows.filter(function (newRow) {
3662 return !_this.parentRows.some(function (oldRow) {
3663 return oldRow === newRow;
3664 });
3665 }); // check if there are expandable rows
3666
3667 if (newExpandableRows.length > 0) {
3668 var diffExpandableRows = diffParentRows.map(function (newRow) {
3669 return newRow.nextElementSibling;
3670 });
3671 var mergedExpandableRows = [].concat(_toConsumableArray(toArray$4(_this.expandableRows)), _toConsumableArray(toArray$4(diffExpandableRows)));
3672
3673 _this._expandableRowsInit(diffExpandableRows);
3674
3675 _this.expandableRows = mergedExpandableRows;
3676 }
3677 } else if (newExpandableRows.length > 0) {
3678 _this._expandableRowsInit(newExpandableRows);
3679
3680 _this.expandableRows = newExpandableRows;
3681 }
3682
3683 _this.expandCells = newExpandCells;
3684 _this.parentRows = newParentRows;
3685 });
3686
3687 _this.container = _element.parentNode;
3688 _this.toolbarEl = _this.element.querySelector(_this.options.selectorToolbar);
3689 _this.batchActionEl = _this.element.querySelector(_this.options.selectorActions);
3690 _this.countEl = _this.element.querySelector(_this.options.selectorCount);
3691 _this.cancelEl = _this.element.querySelector(_this.options.selectorActionCancel);
3692 _this.tableHeaders = _this.element.querySelectorAll('th');
3693 _this.tableBody = _this.element.querySelector(_this.options.selectorTableBody);
3694 _this.expandCells = [];
3695 _this.expandableRows = [];
3696 _this.parentRows = [];
3697
3698 _this.refreshRows();
3699
3700 _this.element.addEventListener('mouseover', function (evt) {
3701 var eventElement = eventMatches(evt, _this.options.selectorChildRow);
3702
3703 if (eventElement) {
3704 _this._expandableHoverToggle(eventElement, true);
3705 }
3706 });
3707
3708 _this.element.addEventListener('click', function (evt) {
3709 var eventElement = eventMatches(evt, _this.options.eventTrigger);
3710
3711 var searchContainer = _this.element.querySelector(_this.options.selectorToolbarSearchContainer);
3712
3713 if (eventElement) {
3714 _this._toggleState(eventElement, evt);
3715 }
3716
3717 if (searchContainer) {
3718 _this._handleDocumentClick(evt);
3719 }
3720 });
3721
3722 _this.element.addEventListener('keydown', _this._keydownHandler);
3723
3724 _this.state = {
3725 checkboxCount: 0
3726 };
3727 return _this;
3728 }
3729
3730 _createClass(DataTableV2, [{
3731 key: "_handleDocumentClick",
3732 value: function _handleDocumentClick(evt) {
3733 var searchContainer = this.element.querySelector(this.options.selectorToolbarSearchContainer);
3734 var searchEvent = eventMatches(evt, this.options.selectorSearchMagnifier);
3735 var activeSearch = searchContainer.classList.contains(this.options.classToolbarSearchActive);
3736
3737 if (searchContainer && searchEvent) {
3738 this.activateSearch(searchContainer);
3739 }
3740
3741 if (activeSearch) {
3742 this.deactivateSearch(searchContainer, evt);
3743 }
3744 }
3745 }, {
3746 key: "activateSearch",
3747 value: function activateSearch(container) {
3748 var input = container.querySelector(this.options.selectorSearchInput);
3749 container.classList.add(this.options.classToolbarSearchActive);
3750 input.focus();
3751 }
3752 }, {
3753 key: "deactivateSearch",
3754 value: function deactivateSearch(container, evt) {
3755 var trigger = container.querySelector(this.options.selectorSearchMagnifier);
3756 var input = container.querySelector(this.options.selectorSearchInput);
3757 var svg = trigger.querySelector('svg');
3758
3759 if (input.value.length === 0 && evt.target !== input && evt.target !== trigger && evt.target !== svg) {
3760 container.classList.remove(this.options.classToolbarSearchActive);
3761 trigger.focus();
3762 }
3763
3764 if (evt.which === 27 && evt.target === input) {
3765 container.classList.remove(this.options.classToolbarSearchActive);
3766 trigger.focus();
3767 }
3768 }
3769 }, {
3770 key: "_changeState",
3771 value: function _changeState(detail, callback) {
3772 this[this.constructor.eventHandlers[detail.group]](detail);
3773 callback();
3774 }
3775 }], [{
3776 key: "options",
3777 get: function get() {
3778 var prefix = settings_1.prefix;
3779 return {
3780 selectorInit: "[data-table".concat(suffix, "]"),
3781 selectorToolbar: ".".concat(prefix, "--table--toolbar"),
3782 selectorActions: ".".concat(prefix, "--batch-actions"),
3783 selectorCount: '[data-items-selected]',
3784 selectorActionCancel: ".".concat(prefix, "--batch-summary__cancel"),
3785 selectorCheckbox: ".".concat(prefix, "--checkbox"),
3786 selectorExpandCells: "td.".concat(prefix, "--table-expand").concat(suffix),
3787 selectorExpandableRows: ".".concat(prefix, "--expandable-row").concat(suffix),
3788 selectorParentRows: ".".concat(prefix, "--parent-row").concat(suffix),
3789 selectorChildRow: '[data-child-row]',
3790 selectorTableBody: 'tbody',
3791 selectorTableSort: ".".concat(prefix, "--table-sort").concat(suffix),
3792 selectorTableSelected: ".".concat(prefix, "--data-table").concat(suffix, "--selected"),
3793 selectorToolbarSearchContainer: ".".concat(prefix, "--toolbar-search-container-expandable"),
3794 selectorSearchMagnifier: ".".concat(prefix, "--search-magnifier"),
3795 selectorSearchInput: ".".concat(prefix, "--search-input"),
3796 classExpandableRow: "".concat(prefix, "--expandable-row").concat(suffix),
3797 classExpandableRowHidden: "".concat(prefix, "--expandable-row--hidden").concat(suffix),
3798 classExpandableRowHover: "".concat(prefix, "--expandable-row--hover").concat(suffix),
3799 classTableSortAscending: "".concat(prefix, "--table-sort").concat(suffix, "--ascending"),
3800 classTableSortActive: "".concat(prefix, "--table-sort").concat(suffix, "--active"),
3801 classToolbarSearchActive: "".concat(prefix, "--toolbar-search-container-active"),
3802 classActionBarActive: "".concat(prefix, "--batch-actions--active"),
3803 classTableSelected: "".concat(prefix, "--data-table").concat(suffix, "--selected"),
3804 eventBeforeExpand: "data-table".concat(suffix, "-beforetoggleexpand"),
3805 eventAfterExpand: "data-table".concat(suffix, "-aftertoggleexpand"),
3806 eventBeforeSort: "data-table".concat(suffix, "-beforetogglesort"),
3807 eventAfterSort: "data-table".concat(suffix, "-aftertogglesort"),
3808 eventTrigger: '[data-event]',
3809 eventParentContainer: '[data-parent-row]'
3810 };
3811 }
3812 }]);
3813
3814 return DataTableV2;
3815 }(mixin(createComponent, initComponentBySearch, eventedState));
3816
3817 _defineProperty(DataTableV2, "components",
3818 /* #__PURE_CLASS_PROPERTY__ */
3819 new WeakMap());
3820
3821 _defineProperty(DataTableV2, "eventHandlers",
3822 /* #__PURE_CLASS_PROPERTY__ */
3823 {
3824 expand: '_rowExpandToggle',
3825 sort: '_sortToggle',
3826 select: '_selectToggle',
3827 'select-all': '_selectAllToggle',
3828 'action-bar-cancel': '_actionBarCancel'
3829 });
3830
3831 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3832
3833 function createCommonjsModule(fn, module) {
3834 return module = { exports: {} }, fn(module, module.exports), module.exports;
3835 }
3836
3837 var flatpickr = createCommonjsModule(function (module, exports) {
3838 /* flatpickr v4.5.7, @license MIT */
3839 (function (global, factory) {
3840 module.exports = factory();
3841 }(commonjsGlobal, function () {
3842 /*! *****************************************************************************
3843 Copyright (c) Microsoft Corporation. All rights reserved.
3844 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
3845 this file except in compliance with the License. You may obtain a copy of the
3846 License at http://www.apache.org/licenses/LICENSE-2.0
3847
3848 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
3849 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
3850 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
3851 MERCHANTABLITY OR NON-INFRINGEMENT.
3852
3853 See the Apache Version 2.0 License for specific language governing permissions
3854 and limitations under the License.
3855 ***************************************************************************** */
3856
3857 var __assign = function() {
3858 __assign = Object.assign || function __assign(t) {
3859 for (var s, i = 1, n = arguments.length; i < n; i++) {
3860 s = arguments[i];
3861 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
3862 }
3863 return t;
3864 };
3865 return __assign.apply(this, arguments);
3866 };
3867
3868 var HOOKS = [
3869 "onChange",
3870 "onClose",
3871 "onDayCreate",
3872 "onDestroy",
3873 "onKeyDown",
3874 "onMonthChange",
3875 "onOpen",
3876 "onParseConfig",
3877 "onReady",
3878 "onValueUpdate",
3879 "onYearChange",
3880 "onPreCalendarPosition",
3881 ];
3882 var defaults = {
3883 _disable: [],
3884 _enable: [],
3885 allowInput: false,
3886 altFormat: "F j, Y",
3887 altInput: false,
3888 altInputClass: "form-control input",
3889 animate: typeof window === "object" &&
3890 window.navigator.userAgent.indexOf("MSIE") === -1,
3891 ariaDateFormat: "F j, Y",
3892 clickOpens: true,
3893 closeOnSelect: true,
3894 conjunction: ", ",
3895 dateFormat: "Y-m-d",
3896 defaultHour: 12,
3897 defaultMinute: 0,
3898 defaultSeconds: 0,
3899 disable: [],
3900 disableMobile: false,
3901 enable: [],
3902 enableSeconds: false,
3903 enableTime: false,
3904 errorHandler: function (err) {
3905 return typeof console !== "undefined" && console.warn(err);
3906 },
3907 getWeek: function (givenDate) {
3908 var date = new Date(givenDate.getTime());
3909 date.setHours(0, 0, 0, 0);
3910 // Thursday in current week decides the year.
3911 date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
3912 // January 4 is always in week 1.
3913 var week1 = new Date(date.getFullYear(), 0, 4);
3914 // Adjust to Thursday in week 1 and count number of weeks from date to week1.
3915 return (1 +
3916 Math.round(((date.getTime() - week1.getTime()) / 86400000 -
3917 3 +
3918 ((week1.getDay() + 6) % 7)) /
3919 7));
3920 },
3921 hourIncrement: 1,
3922 ignoredFocusElements: [],
3923 inline: false,
3924 locale: "default",
3925 minuteIncrement: 5,
3926 mode: "single",
3927 nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
3928 noCalendar: false,
3929 now: new Date(),
3930 onChange: [],
3931 onClose: [],
3932 onDayCreate: [],
3933 onDestroy: [],
3934 onKeyDown: [],
3935 onMonthChange: [],
3936 onOpen: [],
3937 onParseConfig: [],
3938 onReady: [],
3939 onValueUpdate: [],
3940 onYearChange: [],
3941 onPreCalendarPosition: [],
3942 plugins: [],
3943 position: "auto",
3944 positionElement: undefined,
3945 prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
3946 shorthandCurrentMonth: false,
3947 showMonths: 1,
3948 static: false,
3949 time_24hr: false,
3950 weekNumbers: false,
3951 wrap: false
3952 };
3953
3954 var english = {
3955 weekdays: {
3956 shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
3957 longhand: [
3958 "Sunday",
3959 "Monday",
3960 "Tuesday",
3961 "Wednesday",
3962 "Thursday",
3963 "Friday",
3964 "Saturday",
3965 ]
3966 },
3967 months: {
3968 shorthand: [
3969 "Jan",
3970 "Feb",
3971 "Mar",
3972 "Apr",
3973 "May",
3974 "Jun",
3975 "Jul",
3976 "Aug",
3977 "Sep",
3978 "Oct",
3979 "Nov",
3980 "Dec",
3981 ],
3982 longhand: [
3983 "January",
3984 "February",
3985 "March",
3986 "April",
3987 "May",
3988 "June",
3989 "July",
3990 "August",
3991 "September",
3992 "October",
3993 "November",
3994 "December",
3995 ]
3996 },
3997 daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
3998 firstDayOfWeek: 0,
3999 ordinal: function (nth) {
4000 var s = nth % 100;
4001 if (s > 3 && s < 21)
4002 return "th";
4003 switch (s % 10) {
4004 case 1:
4005 return "st";
4006 case 2:
4007 return "nd";
4008 case 3:
4009 return "rd";
4010 default:
4011 return "th";
4012 }
4013 },
4014 rangeSeparator: " to ",
4015 weekAbbreviation: "Wk",
4016 scrollTitle: "Scroll to increment",
4017 toggleTitle: "Click to toggle",
4018 amPM: ["AM", "PM"],
4019 yearAriaLabel: "Year"
4020 };
4021
4022 var pad = function (number) { return ("0" + number).slice(-2); };
4023 var int = function (bool) { return (bool === true ? 1 : 0); };
4024 /* istanbul ignore next */
4025 function debounce(func, wait, immediate) {
4026 if (immediate === void 0) { immediate = false; }
4027 var timeout;
4028 return function () {
4029 var context = this, args = arguments;
4030 timeout !== null && clearTimeout(timeout);
4031 timeout = window.setTimeout(function () {
4032 timeout = null;
4033 if (!immediate)
4034 func.apply(context, args);
4035 }, wait);
4036 if (immediate && !timeout)
4037 func.apply(context, args);
4038 };
4039 }
4040 var arrayify = function (obj) {
4041 return obj instanceof Array ? obj : [obj];
4042 };
4043
4044 function toggleClass(elem, className, bool) {
4045 if (bool === true)
4046 return elem.classList.add(className);
4047 elem.classList.remove(className);
4048 }
4049 function createElement(tag, className, content) {
4050 var e = window.document.createElement(tag);
4051 className = className || "";
4052 content = content || "";
4053 e.className = className;
4054 if (content !== undefined)
4055 e.textContent = content;
4056 return e;
4057 }
4058 function clearNode(node) {
4059 while (node.firstChild)
4060 node.removeChild(node.firstChild);
4061 }
4062 function findParent(node, condition) {
4063 if (condition(node))
4064 return node;
4065 else if (node.parentNode)
4066 return findParent(node.parentNode, condition);
4067 return undefined; // nothing found
4068 }
4069 function createNumberInput(inputClassName, opts) {
4070 var wrapper = createElement("div", "numInputWrapper"), numInput = createElement("input", "numInput " + inputClassName), arrowUp = createElement("span", "arrowUp"), arrowDown = createElement("span", "arrowDown");
4071 if (navigator.userAgent.indexOf("MSIE 9.0") === -1) {
4072 numInput.type = "number";
4073 }
4074 else {
4075 numInput.type = "text";
4076 numInput.pattern = "\\d*";
4077 }
4078 if (opts !== undefined)
4079 for (var key in opts)
4080 numInput.setAttribute(key, opts[key]);
4081 wrapper.appendChild(numInput);
4082 wrapper.appendChild(arrowUp);
4083 wrapper.appendChild(arrowDown);
4084 return wrapper;
4085 }
4086 function getEventTarget(event) {
4087 if (typeof event.composedPath === "function") {
4088 var path = event.composedPath();
4089 return path[0];
4090 }
4091 return event.target;
4092 }
4093
4094 var do_nothing = function () { return undefined; };
4095 var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? "shorthand" : "longhand"][monthNumber]; };
4096 var revFormat = {
4097 D: do_nothing,
4098 F: function (dateObj, monthName, locale) {
4099 dateObj.setMonth(locale.months.longhand.indexOf(monthName));
4100 },
4101 G: function (dateObj, hour) {
4102 dateObj.setHours(parseFloat(hour));
4103 },
4104 H: function (dateObj, hour) {
4105 dateObj.setHours(parseFloat(hour));
4106 },
4107 J: function (dateObj, day) {
4108 dateObj.setDate(parseFloat(day));
4109 },
4110 K: function (dateObj, amPM, locale) {
4111 dateObj.setHours((dateObj.getHours() % 12) +
4112 12 * int(new RegExp(locale.amPM[1], "i").test(amPM)));
4113 },
4114 M: function (dateObj, shortMonth, locale) {
4115 dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));
4116 },
4117 S: function (dateObj, seconds) {
4118 dateObj.setSeconds(parseFloat(seconds));
4119 },
4120 U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },
4121 W: function (dateObj, weekNum) {
4122 var weekNumber = parseInt(weekNum);
4123 return new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);
4124 },
4125 Y: function (dateObj, year) {
4126 dateObj.setFullYear(parseFloat(year));
4127 },
4128 Z: function (_, ISODate) { return new Date(ISODate); },
4129 d: function (dateObj, day) {
4130 dateObj.setDate(parseFloat(day));
4131 },
4132 h: function (dateObj, hour) {
4133 dateObj.setHours(parseFloat(hour));
4134 },
4135 i: function (dateObj, minutes) {
4136 dateObj.setMinutes(parseFloat(minutes));
4137 },
4138 j: function (dateObj, day) {
4139 dateObj.setDate(parseFloat(day));
4140 },
4141 l: do_nothing,
4142 m: function (dateObj, month) {
4143 dateObj.setMonth(parseFloat(month) - 1);
4144 },
4145 n: function (dateObj, month) {
4146 dateObj.setMonth(parseFloat(month) - 1);
4147 },
4148 s: function (dateObj, seconds) {
4149 dateObj.setSeconds(parseFloat(seconds));
4150 },
4151 u: function (_, unixMillSeconds) {
4152 return new Date(parseFloat(unixMillSeconds));
4153 },
4154 w: do_nothing,
4155 y: function (dateObj, year) {
4156 dateObj.setFullYear(2000 + parseFloat(year));
4157 }
4158 };
4159 var tokenRegex = {
4160 D: "(\\w+)",
4161 F: "(\\w+)",
4162 G: "(\\d\\d|\\d)",
4163 H: "(\\d\\d|\\d)",
4164 J: "(\\d\\d|\\d)\\w+",
4165 K: "",
4166 M: "(\\w+)",
4167 S: "(\\d\\d|\\d)",
4168 U: "(.+)",
4169 W: "(\\d\\d|\\d)",
4170 Y: "(\\d{4})",
4171 Z: "(.+)",
4172 d: "(\\d\\d|\\d)",
4173 h: "(\\d\\d|\\d)",
4174 i: "(\\d\\d|\\d)",
4175 j: "(\\d\\d|\\d)",
4176 l: "(\\w+)",
4177 m: "(\\d\\d|\\d)",
4178 n: "(\\d\\d|\\d)",
4179 s: "(\\d\\d|\\d)",
4180 u: "(.+)",
4181 w: "(\\d\\d|\\d)",
4182 y: "(\\d{2})"
4183 };
4184 var formats = {
4185 // get the date in UTC
4186 Z: function (date) { return date.toISOString(); },
4187 // weekday name, short, e.g. Thu
4188 D: function (date, locale, options) {
4189 return locale.weekdays.shorthand[formats.w(date, locale, options)];
4190 },
4191 // full month name e.g. January
4192 F: function (date, locale, options) {
4193 return monthToStr(formats.n(date, locale, options) - 1, false, locale);
4194 },
4195 // padded hour 1-12
4196 G: function (date, locale, options) {
4197 return pad(formats.h(date, locale, options));
4198 },
4199 // hours with leading zero e.g. 03
4200 H: function (date) { return pad(date.getHours()); },
4201 // day (1-30) with ordinal suffix e.g. 1st, 2nd
4202 J: function (date, locale) {
4203 return locale.ordinal !== undefined
4204 ? date.getDate() + locale.ordinal(date.getDate())
4205 : date.getDate();
4206 },
4207 // AM/PM
4208 K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },
4209 // shorthand month e.g. Jan, Sep, Oct, etc
4210 M: function (date, locale) {
4211 return monthToStr(date.getMonth(), true, locale);
4212 },
4213 // seconds 00-59
4214 S: function (date) { return pad(date.getSeconds()); },
4215 // unix timestamp
4216 U: function (date) { return date.getTime() / 1000; },
4217 W: function (date, _, options) {
4218 return options.getWeek(date);
4219 },
4220 // full year e.g. 2016
4221 Y: function (date) { return date.getFullYear(); },
4222 // day in month, padded (01-30)
4223 d: function (date) { return pad(date.getDate()); },
4224 // hour from 1-12 (am/pm)
4225 h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },
4226 // minutes, padded with leading zero e.g. 09
4227 i: function (date) { return pad(date.getMinutes()); },
4228 // day in month (1-30)
4229 j: function (date) { return date.getDate(); },
4230 // weekday name, full, e.g. Thursday
4231 l: function (date, locale) {
4232 return locale.weekdays.longhand[date.getDay()];
4233 },
4234 // padded month number (01-12)
4235 m: function (date) { return pad(date.getMonth() + 1); },
4236 // the month number (1-12)
4237 n: function (date) { return date.getMonth() + 1; },
4238 // seconds 0-59
4239 s: function (date) { return date.getSeconds(); },
4240 // Unix Milliseconds
4241 u: function (date) { return date.getTime(); },
4242 // number of the day of the week
4243 w: function (date) { return date.getDay(); },
4244 // last two digits of year e.g. 16 for 2016
4245 y: function (date) { return String(date.getFullYear()).substring(2); }
4246 };
4247
4248 var createDateFormatter = function (_a) {
4249 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;
4250 return function (dateObj, frmt, overrideLocale) {
4251 var locale = overrideLocale || l10n;
4252 if (config.formatDate !== undefined) {
4253 return config.formatDate(dateObj, frmt, locale);
4254 }
4255 return frmt
4256 .split("")
4257 .map(function (c, i, arr) {
4258 return formats[c] && arr[i - 1] !== "\\"
4259 ? formats[c](dateObj, locale, config)
4260 : c !== "\\"
4261 ? c
4262 : "";
4263 })
4264 .join("");
4265 };
4266 };
4267 var createDateParser = function (_a) {
4268 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;
4269 return function (date, givenFormat, timeless, customLocale) {
4270 if (date !== 0 && !date)
4271 return undefined;
4272 var locale = customLocale || l10n;
4273 var parsedDate;
4274 var date_orig = date;
4275 if (date instanceof Date)
4276 parsedDate = new Date(date.getTime());
4277 else if (typeof date !== "string" &&
4278 date.toFixed !== undefined // timestamp
4279 )
4280 // create a copy
4281 parsedDate = new Date(date);
4282 else if (typeof date === "string") {
4283 // date string
4284 var format = givenFormat || (config || defaults).dateFormat;
4285 var datestr = String(date).trim();
4286 if (datestr === "today") {
4287 parsedDate = new Date();
4288 timeless = true;
4289 }
4290 else if (/Z$/.test(datestr) ||
4291 /GMT$/.test(datestr) // datestrings w/ timezone
4292 )
4293 parsedDate = new Date(date);
4294 else if (config && config.parseDate)
4295 parsedDate = config.parseDate(date, format);
4296 else {
4297 parsedDate =
4298 !config || !config.noCalendar
4299 ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)
4300 : new Date(new Date().setHours(0, 0, 0, 0));
4301 var matched = void 0, ops = [];
4302 for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
4303 var token_1 = format[i];
4304 var isBackSlash = token_1 === "\\";
4305 var escaped = format[i - 1] === "\\" || isBackSlash;
4306 if (tokenRegex[token_1] && !escaped) {
4307 regexStr += tokenRegex[token_1];
4308 var match = new RegExp(regexStr).exec(date);
4309 if (match && (matched = true)) {
4310 ops[token_1 !== "Y" ? "push" : "unshift"]({
4311 fn: revFormat[token_1],
4312 val: match[++matchIndex]
4313 });
4314 }
4315 }
4316 else if (!isBackSlash)
4317 regexStr += "."; // don't really care
4318 ops.forEach(function (_a) {
4319 var fn = _a.fn, val = _a.val;
4320 return (parsedDate = fn(parsedDate, val, locale) || parsedDate);
4321 });
4322 }
4323 parsedDate = matched ? parsedDate : undefined;
4324 }
4325 }
4326 /* istanbul ignore next */
4327 if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {
4328 config.errorHandler(new Error("Invalid date provided: " + date_orig));
4329 return undefined;
4330 }
4331 if (timeless === true)
4332 parsedDate.setHours(0, 0, 0, 0);
4333 return parsedDate;
4334 };
4335 };
4336 /**
4337 * Compute the difference in dates, measured in ms
4338 */
4339 function compareDates(date1, date2, timeless) {
4340 if (timeless === void 0) { timeless = true; }
4341 if (timeless !== false) {
4342 return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -
4343 new Date(date2.getTime()).setHours(0, 0, 0, 0));
4344 }
4345 return date1.getTime() - date2.getTime();
4346 }
4347 var isBetween = function (ts, ts1, ts2) {
4348 return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);
4349 };
4350 var duration = {
4351 DAY: 86400000
4352 };
4353
4354 if (typeof Object.assign !== "function") {
4355 Object.assign = function (target) {
4356 var args = [];
4357 for (var _i = 1; _i < arguments.length; _i++) {
4358 args[_i - 1] = arguments[_i];
4359 }
4360 if (!target) {
4361 throw TypeError("Cannot convert undefined or null to object");
4362 }
4363 var _loop_1 = function (source) {
4364 if (source) {
4365 Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });
4366 }
4367 };
4368 for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
4369 var source = args_1[_a];
4370 _loop_1(source);
4371 }
4372 return target;
4373 };
4374 }
4375
4376 var DEBOUNCED_CHANGE_MS = 300;
4377 function FlatpickrInstance(element, instanceConfig) {
4378 var self = {
4379 config: __assign({}, flatpickr.defaultConfig),
4380 l10n: english
4381 };
4382 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
4383 self._handlers = [];
4384 self._bind = bind;
4385 self._setHoursFromDate = setHoursFromDate;
4386 self._positionCalendar = positionCalendar;
4387 self.changeMonth = changeMonth;
4388 self.changeYear = changeYear;
4389 self.clear = clear;
4390 self.close = close;
4391 self._createElement = createElement;
4392 self.destroy = destroy;
4393 self.isEnabled = isEnabled;
4394 self.jumpToDate = jumpToDate;
4395 self.open = open;
4396 self.redraw = redraw;
4397 self.set = set;
4398 self.setDate = setDate;
4399 self.toggle = toggle;
4400 function setupHelperFunctions() {
4401 self.utils = {
4402 getDaysInMonth: function (month, yr) {
4403 if (month === void 0) { month = self.currentMonth; }
4404 if (yr === void 0) { yr = self.currentYear; }
4405 if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))
4406 return 29;
4407 return self.l10n.daysInMonth[month];
4408 }
4409 };
4410 }
4411 function init() {
4412 self.element = self.input = element;
4413 self.isOpen = false;
4414 parseConfig();
4415 setupLocale();
4416 setupInputs();
4417 setupDates();
4418 setupHelperFunctions();
4419 if (!self.isMobile)
4420 build();
4421 bindEvents();
4422 if (self.selectedDates.length || self.config.noCalendar) {
4423 if (self.config.enableTime) {
4424 setHoursFromDate(self.config.noCalendar
4425 ? self.latestSelectedDateObj || self.config.minDate
4426 : undefined);
4427 }
4428 updateValue(false);
4429 }
4430 setCalendarWidth();
4431 self.showTimeInput =
4432 self.selectedDates.length > 0 || self.config.noCalendar;
4433 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
4434 /* TODO: investigate this further
4435
4436 Currently, there is weird positioning behavior in safari causing pages
4437 to scroll up. https://github.com/chmln/flatpickr/issues/563
4438
4439 However, most browsers are not Safari and positioning is expensive when used
4440 in scale. https://github.com/chmln/flatpickr/issues/1096
4441 */
4442 if (!self.isMobile && isSafari) {
4443 positionCalendar();
4444 }
4445 triggerEvent("onReady");
4446 }
4447 function bindToInstance(fn) {
4448 return fn.bind(self);
4449 }
4450 function setCalendarWidth() {
4451 var config = self.config;
4452 if (config.weekNumbers === false && config.showMonths === 1)
4453 return;
4454 else if (config.noCalendar !== true) {
4455 window.requestAnimationFrame(function () {
4456 if (self.calendarContainer !== undefined) {
4457 self.calendarContainer.style.visibility = "hidden";
4458 self.calendarContainer.style.display = "block";
4459 }
4460 if (self.daysContainer !== undefined) {
4461 var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;
4462 self.daysContainer.style.width = daysWidth + "px";
4463 self.calendarContainer.style.width =
4464 daysWidth +
4465 (self.weekWrapper !== undefined
4466 ? self.weekWrapper.offsetWidth
4467 : 0) +
4468 "px";
4469 self.calendarContainer.style.removeProperty("visibility");
4470 self.calendarContainer.style.removeProperty("display");
4471 }
4472 });
4473 }
4474 }
4475 /**
4476 * The handler for all events targeting the time inputs
4477 */
4478 function updateTime(e) {
4479 if (self.selectedDates.length === 0) {
4480 setDefaultTime();
4481 }
4482 if (e !== undefined && e.type !== "blur") {
4483 timeWrapper(e);
4484 }
4485 var prevValue = self._input.value;
4486 setHoursFromInputs();
4487 updateValue();
4488 if (self._input.value !== prevValue) {
4489 self._debouncedChange();
4490 }
4491 }
4492 function ampm2military(hour, amPM) {
4493 return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);
4494 }
4495 function military2ampm(hour) {
4496 switch (hour % 24) {
4497 case 0:
4498 case 12:
4499 return 12;
4500 default:
4501 return hour % 12;
4502 }
4503 }
4504 /**
4505 * Syncs the selected date object time with user's time input
4506 */
4507 function setHoursFromInputs() {
4508 if (self.hourElement === undefined || self.minuteElement === undefined)
4509 return;
4510 var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined
4511 ? (parseInt(self.secondElement.value, 10) || 0) % 60
4512 : 0;
4513 if (self.amPM !== undefined) {
4514 hours = ampm2military(hours, self.amPM.textContent);
4515 }
4516 var limitMinHours = self.config.minTime !== undefined ||
4517 (self.config.minDate &&
4518 self.minDateHasTime &&
4519 self.latestSelectedDateObj &&
4520 compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===
4521 0);
4522 var limitMaxHours = self.config.maxTime !== undefined ||
4523 (self.config.maxDate &&
4524 self.maxDateHasTime &&
4525 self.latestSelectedDateObj &&
4526 compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===
4527 0);
4528 if (limitMaxHours) {
4529 var maxTime = self.config.maxTime !== undefined
4530 ? self.config.maxTime
4531 : self.config.maxDate;
4532 hours = Math.min(hours, maxTime.getHours());
4533 if (hours === maxTime.getHours())
4534 minutes = Math.min(minutes, maxTime.getMinutes());
4535 if (minutes === maxTime.getMinutes())
4536 seconds = Math.min(seconds, maxTime.getSeconds());
4537 }
4538 if (limitMinHours) {
4539 var minTime = self.config.minTime !== undefined
4540 ? self.config.minTime
4541 : self.config.minDate;
4542 hours = Math.max(hours, minTime.getHours());
4543 if (hours === minTime.getHours())
4544 minutes = Math.max(minutes, minTime.getMinutes());
4545 if (minutes === minTime.getMinutes())
4546 seconds = Math.max(seconds, minTime.getSeconds());
4547 }
4548 setHours(hours, minutes, seconds);
4549 }
4550 /**
4551 * Syncs time input values with a date
4552 */
4553 function setHoursFromDate(dateObj) {
4554 var date = dateObj || self.latestSelectedDateObj;
4555 if (date)
4556 setHours(date.getHours(), date.getMinutes(), date.getSeconds());
4557 }
4558 function setDefaultHours() {
4559 var hours = self.config.defaultHour;
4560 var minutes = self.config.defaultMinute;
4561 var seconds = self.config.defaultSeconds;
4562 if (self.config.minDate !== undefined) {
4563 var min_hr = self.config.minDate.getHours();
4564 var min_minutes = self.config.minDate.getMinutes();
4565 hours = Math.max(hours, min_hr);
4566 if (hours === min_hr)
4567 minutes = Math.max(min_minutes, minutes);
4568 if (hours === min_hr && minutes === min_minutes)
4569 seconds = self.config.minDate.getSeconds();
4570 }
4571 if (self.config.maxDate !== undefined) {
4572 var max_hr = self.config.maxDate.getHours();
4573 var max_minutes = self.config.maxDate.getMinutes();
4574 hours = Math.min(hours, max_hr);
4575 if (hours === max_hr)
4576 minutes = Math.min(max_minutes, minutes);
4577 if (hours === max_hr && minutes === max_minutes)
4578 seconds = self.config.maxDate.getSeconds();
4579 }
4580 setHours(hours, minutes, seconds);
4581 }
4582 /**
4583 * Sets the hours, minutes, and optionally seconds
4584 * of the latest selected date object and the
4585 * corresponding time inputs
4586 * @param {Number} hours the hour. whether its military
4587 * or am-pm gets inferred from config
4588 * @param {Number} minutes the minutes
4589 * @param {Number} seconds the seconds (optional)
4590 */
4591 function setHours(hours, minutes, seconds) {
4592 if (self.latestSelectedDateObj !== undefined) {
4593 self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);
4594 }
4595 if (!self.hourElement || !self.minuteElement || self.isMobile)
4596 return;
4597 self.hourElement.value = pad(!self.config.time_24hr
4598 ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)
4599 : hours);
4600 self.minuteElement.value = pad(minutes);
4601 if (self.amPM !== undefined)
4602 self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];
4603 if (self.secondElement !== undefined)
4604 self.secondElement.value = pad(seconds);
4605 }
4606 /**
4607 * Handles the year input and incrementing events
4608 * @param {Event} event the keyup or increment event
4609 */
4610 function onYearInput(event) {
4611 var year = parseInt(event.target.value) + (event.delta || 0);
4612 if (year / 1000 > 1 ||
4613 (event.key === "Enter" && !/[^\d]/.test(year.toString()))) {
4614 changeYear(year);
4615 }
4616 }
4617 /**
4618 * Essentially addEventListener + tracking
4619 * @param {Element} element the element to addEventListener to
4620 * @param {String} event the event name
4621 * @param {Function} handler the event handler
4622 */
4623 function bind(element, event, handler, options) {
4624 if (event instanceof Array)
4625 return event.forEach(function (ev) { return bind(element, ev, handler, options); });
4626 if (element instanceof Array)
4627 return element.forEach(function (el) { return bind(el, event, handler, options); });
4628 element.addEventListener(event, handler, options);
4629 self._handlers.push({
4630 element: element,
4631 event: event,
4632 handler: handler,
4633 options: options
4634 });
4635 }
4636 /**
4637 * A mousedown handler which mimics click.
4638 * Minimizes latency, since we don't need to wait for mouseup in most cases.
4639 * Also, avoids handling right clicks.
4640 *
4641 * @param {Function} handler the event handler
4642 */
4643 function onClick(handler) {
4644 return function (evt) {
4645 evt.which === 1 && handler(evt);
4646 };
4647 }
4648 function triggerChange() {
4649 triggerEvent("onChange");
4650 }
4651 /**
4652 * Adds all the necessary event listeners
4653 */
4654 function bindEvents() {
4655 if (self.config.wrap) {
4656 ["open", "close", "toggle", "clear"].forEach(function (evt) {
4657 Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) {
4658 return bind(el, "click", self[evt]);
4659 });
4660 });
4661 }
4662 if (self.isMobile) {
4663 setupMobile();
4664 return;
4665 }
4666 var debouncedResize = debounce(onResize, 50);
4667 self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);
4668 if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))
4669 bind(self.daysContainer, "mouseover", function (e) {
4670 if (self.config.mode === "range")
4671 onMouseOver(e.target);
4672 });
4673 bind(window.document.body, "keydown", onKeyDown);
4674 if (!self.config.static)
4675 bind(self._input, "keydown", onKeyDown);
4676 if (!self.config.inline && !self.config.static)
4677 bind(window, "resize", debouncedResize);
4678 if (window.ontouchstart !== undefined)
4679 bind(window.document, "click", documentClick);
4680 else
4681 bind(window.document, "mousedown", onClick(documentClick));
4682 bind(window.document, "focus", documentClick, { capture: true });
4683 if (self.config.clickOpens === true) {
4684 bind(self._input, "focus", self.open);
4685 bind(self._input, "mousedown", onClick(self.open));
4686 }
4687 if (self.daysContainer !== undefined) {
4688 bind(self.monthNav, "mousedown", onClick(onMonthNavClick));
4689 bind(self.monthNav, ["keyup", "increment"], onYearInput);
4690 bind(self.daysContainer, "mousedown", onClick(selectDate));
4691 }
4692 if (self.timeContainer !== undefined &&
4693 self.minuteElement !== undefined &&
4694 self.hourElement !== undefined) {
4695 var selText = function (e) {
4696 return e.target.select();
4697 };
4698 bind(self.timeContainer, ["increment"], updateTime);
4699 bind(self.timeContainer, "blur", updateTime, { capture: true });
4700 bind(self.timeContainer, "mousedown", onClick(timeIncrement));
4701 bind([self.hourElement, self.minuteElement], ["focus", "click"], selText);
4702 if (self.secondElement !== undefined)
4703 bind(self.secondElement, "focus", function () { return self.secondElement && self.secondElement.select(); });
4704 if (self.amPM !== undefined) {
4705 bind(self.amPM, "mousedown", onClick(function (e) {
4706 updateTime(e);
4707 triggerChange();
4708 }));
4709 }
4710 }
4711 }
4712 /**
4713 * Set the calendar view to a particular date.
4714 * @param {Date} jumpDate the date to set the view to
4715 */
4716 function jumpToDate(jumpDate) {
4717 var jumpTo = jumpDate !== undefined
4718 ? self.parseDate(jumpDate)
4719 : self.latestSelectedDateObj ||
4720 (self.config.minDate && self.config.minDate > self.now
4721 ? self.config.minDate
4722 : self.config.maxDate && self.config.maxDate < self.now
4723 ? self.config.maxDate
4724 : self.now);
4725 try {
4726 if (jumpTo !== undefined) {
4727 self.currentYear = jumpTo.getFullYear();
4728 self.currentMonth = jumpTo.getMonth();
4729 }
4730 }
4731 catch (e) {
4732 /* istanbul ignore next */
4733 e.message = "Invalid date supplied: " + jumpTo;
4734 self.config.errorHandler(e);
4735 }
4736 self.redraw();
4737 }
4738 /**
4739 * The up/down arrow handler for time inputs
4740 * @param {Event} e the click event
4741 */
4742 function timeIncrement(e) {
4743 if (~e.target.className.indexOf("arrow"))
4744 incrementNumInput(e, e.target.classList.contains("arrowUp") ? 1 : -1);
4745 }
4746 /**
4747 * Increments/decrements the value of input associ-
4748 * ated with the up/down arrow by dispatching an
4749 * "increment" event on the input.
4750 *
4751 * @param {Event} e the click event
4752 * @param {Number} delta the diff (usually 1 or -1)
4753 * @param {Element} inputElem the input element
4754 */
4755 function incrementNumInput(e, delta, inputElem) {
4756 var target = e && e.target;
4757 var input = inputElem ||
4758 (target && target.parentNode && target.parentNode.firstChild);
4759 var event = createEvent("increment");
4760 event.delta = delta;
4761 input && input.dispatchEvent(event);
4762 }
4763 function build() {
4764 var fragment = window.document.createDocumentFragment();
4765 self.calendarContainer = createElement("div", "flatpickr-calendar");
4766 self.calendarContainer.tabIndex = -1;
4767 if (!self.config.noCalendar) {
4768 fragment.appendChild(buildMonthNav());
4769 self.innerContainer = createElement("div", "flatpickr-innerContainer");
4770 if (self.config.weekNumbers) {
4771 var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;
4772 self.innerContainer.appendChild(weekWrapper);
4773 self.weekNumbers = weekNumbers;
4774 self.weekWrapper = weekWrapper;
4775 }
4776 self.rContainer = createElement("div", "flatpickr-rContainer");
4777 self.rContainer.appendChild(buildWeekdays());
4778 if (!self.daysContainer) {
4779 self.daysContainer = createElement("div", "flatpickr-days");
4780 self.daysContainer.tabIndex = -1;
4781 }
4782 buildDays();
4783 self.rContainer.appendChild(self.daysContainer);
4784 self.innerContainer.appendChild(self.rContainer);
4785 fragment.appendChild(self.innerContainer);
4786 }
4787 if (self.config.enableTime) {
4788 fragment.appendChild(buildTime());
4789 }
4790 toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range");
4791 toggleClass(self.calendarContainer, "animate", self.config.animate === true);
4792 toggleClass(self.calendarContainer, "multiMonth", self.config.showMonths > 1);
4793 self.calendarContainer.appendChild(fragment);
4794 var customAppend = self.config.appendTo !== undefined &&
4795 self.config.appendTo.nodeType !== undefined;
4796 if (self.config.inline || self.config.static) {
4797 self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
4798 if (self.config.inline) {
4799 if (!customAppend && self.element.parentNode)
4800 self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);
4801 else if (self.config.appendTo !== undefined)
4802 self.config.appendTo.appendChild(self.calendarContainer);
4803 }
4804 if (self.config.static) {
4805 var wrapper = createElement("div", "flatpickr-wrapper");
4806 if (self.element.parentNode)
4807 self.element.parentNode.insertBefore(wrapper, self.element);
4808 wrapper.appendChild(self.element);
4809 if (self.altInput)
4810 wrapper.appendChild(self.altInput);
4811 wrapper.appendChild(self.calendarContainer);
4812 }
4813 }
4814 if (!self.config.static && !self.config.inline)
4815 (self.config.appendTo !== undefined
4816 ? self.config.appendTo
4817 : window.document.body).appendChild(self.calendarContainer);
4818 }
4819 function createDay(className, date, dayNumber, i) {
4820 var dateIsEnabled = isEnabled(date, true), dayElement = createElement("span", "flatpickr-day " + className, date.getDate().toString());
4821 dayElement.dateObj = date;
4822 dayElement.$i = i;
4823 dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));
4824 if (className.indexOf("hidden") === -1 &&
4825 compareDates(date, self.now) === 0) {
4826 self.todayDateElem = dayElement;
4827 dayElement.classList.add("today");
4828 dayElement.setAttribute("aria-current", "date");
4829 }
4830 if (dateIsEnabled) {
4831 dayElement.tabIndex = -1;
4832 if (isDateSelected(date)) {
4833 dayElement.classList.add("selected");
4834 self.selectedDateElem = dayElement;
4835 if (self.config.mode === "range") {
4836 toggleClass(dayElement, "startRange", self.selectedDates[0] &&
4837 compareDates(date, self.selectedDates[0], true) === 0);
4838 toggleClass(dayElement, "endRange", self.selectedDates[1] &&
4839 compareDates(date, self.selectedDates[1], true) === 0);
4840 if (className === "nextMonthDay")
4841 dayElement.classList.add("inRange");
4842 }
4843 }
4844 }
4845 else {
4846 dayElement.classList.add("disabled");
4847 }
4848 if (self.config.mode === "range") {
4849 if (isDateInRange(date) && !isDateSelected(date))
4850 dayElement.classList.add("inRange");
4851 }
4852 if (self.weekNumbers &&
4853 self.config.showMonths === 1 &&
4854 className !== "prevMonthDay" &&
4855 dayNumber % 7 === 1) {
4856 self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='flatpickr-day'>" + self.config.getWeek(date) + "</span>");
4857 }
4858 triggerEvent("onDayCreate", dayElement);
4859 return dayElement;
4860 }
4861 function focusOnDayElem(targetNode) {
4862 targetNode.focus();
4863 if (self.config.mode === "range")
4864 onMouseOver(targetNode);
4865 }
4866 function getFirstAvailableDay(delta) {
4867 var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;
4868 var endMonth = delta > 0 ? self.config.showMonths : -1;
4869 for (var m = startMonth; m != endMonth; m += delta) {
4870 var month = self.daysContainer.children[m];
4871 var startIndex = delta > 0 ? 0 : month.children.length - 1;
4872 var endIndex = delta > 0 ? month.children.length : -1;
4873 for (var i = startIndex; i != endIndex; i += delta) {
4874 var c = month.children[i];
4875 if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj))
4876 return c;
4877 }
4878 }
4879 return undefined;
4880 }
4881 function getNextAvailableDay(current, delta) {
4882 var givenMonth = current.className.indexOf("Month") === -1
4883 ? current.dateObj.getMonth()
4884 : self.currentMonth;
4885 var endMonth = delta > 0 ? self.config.showMonths : -1;
4886 var loopDelta = delta > 0 ? 1 : -1;
4887 for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {
4888 var month = self.daysContainer.children[m];
4889 var startIndex = givenMonth - self.currentMonth === m
4890 ? current.$i + delta
4891 : delta < 0
4892 ? month.children.length - 1
4893 : 0;
4894 var numMonthDays = month.children.length;
4895 for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {
4896 var c = month.children[i];
4897 if (c.className.indexOf("hidden") === -1 &&
4898 isEnabled(c.dateObj) &&
4899 Math.abs(current.$i - i) >= Math.abs(delta))
4900 return focusOnDayElem(c);
4901 }
4902 }
4903 self.changeMonth(loopDelta);
4904 focusOnDay(getFirstAvailableDay(loopDelta), 0);
4905 return undefined;
4906 }
4907 function focusOnDay(current, offset) {
4908 var dayFocused = isInView(document.activeElement || document.body);
4909 var startElem = current !== undefined
4910 ? current
4911 : dayFocused
4912 ? document.activeElement
4913 : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)
4914 ? self.selectedDateElem
4915 : self.todayDateElem !== undefined && isInView(self.todayDateElem)
4916 ? self.todayDateElem
4917 : getFirstAvailableDay(offset > 0 ? 1 : -1);
4918 if (startElem === undefined)
4919 return self._input.focus();
4920 if (!dayFocused)
4921 return focusOnDayElem(startElem);
4922 getNextAvailableDay(startElem, offset);
4923 }
4924 function buildMonthDays(year, month) {
4925 var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;
4926 var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12);
4927 var daysInMonth = self.utils.getDaysInMonth(month), days = window.document.createDocumentFragment(), isMultiMonth = self.config.showMonths > 1, prevMonthDayClass = isMultiMonth ? "prevMonthDay hidden" : "prevMonthDay", nextMonthDayClass = isMultiMonth ? "nextMonthDay hidden" : "nextMonthDay";
4928 var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;
4929 // prepend days from the ending of previous month
4930 for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {
4931 days.appendChild(createDay(prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));
4932 }
4933 // Start at 1 since there is no 0th day
4934 for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
4935 days.appendChild(createDay("", new Date(year, month, dayNumber), dayNumber, dayIndex));
4936 }
4937 // append days from the next month
4938 for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&
4939 (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {
4940 days.appendChild(createDay(nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));
4941 }
4942 //updateNavigationCurrentMonth();
4943 var dayContainer = createElement("div", "dayContainer");
4944 dayContainer.appendChild(days);
4945 return dayContainer;
4946 }
4947 function buildDays() {
4948 if (self.daysContainer === undefined) {
4949 return;
4950 }
4951 clearNode(self.daysContainer);
4952 // TODO: week numbers for each month
4953 if (self.weekNumbers)
4954 clearNode(self.weekNumbers);
4955 var frag = document.createDocumentFragment();
4956 for (var i = 0; i < self.config.showMonths; i++) {
4957 var d = new Date(self.currentYear, self.currentMonth, 1);
4958 d.setMonth(self.currentMonth + i);
4959 frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));
4960 }
4961 self.daysContainer.appendChild(frag);
4962 self.days = self.daysContainer.firstChild;
4963 if (self.config.mode === "range" && self.selectedDates.length === 1) {
4964 onMouseOver();
4965 }
4966 }
4967 function buildMonth() {
4968 var container = createElement("div", "flatpickr-month");
4969 var monthNavFragment = window.document.createDocumentFragment();
4970 var monthElement = createElement("span", "cur-month");
4971 var yearInput = createNumberInput("cur-year", { tabindex: "-1" });
4972 var yearElement = yearInput.getElementsByTagName("input")[0];
4973 yearElement.setAttribute("aria-label", self.l10n.yearAriaLabel);
4974 if (self.config.minDate) {
4975 yearElement.setAttribute("min", self.config.minDate.getFullYear().toString());
4976 }
4977 if (self.config.maxDate) {
4978 yearElement.setAttribute("max", self.config.maxDate.getFullYear().toString());
4979 yearElement.disabled =
4980 !!self.config.minDate &&
4981 self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
4982 }
4983 var currentMonth = createElement("div", "flatpickr-current-month");
4984 currentMonth.appendChild(monthElement);
4985 currentMonth.appendChild(yearInput);
4986 monthNavFragment.appendChild(currentMonth);
4987 container.appendChild(monthNavFragment);
4988 return {
4989 container: container,
4990 yearElement: yearElement,
4991 monthElement: monthElement
4992 };
4993 }
4994 function buildMonths() {
4995 clearNode(self.monthNav);
4996 self.monthNav.appendChild(self.prevMonthNav);
4997 if (self.config.showMonths) {
4998 self.yearElements = [];
4999 self.monthElements = [];
5000 }
5001 for (var m = self.config.showMonths; m--;) {
5002 var month = buildMonth();
5003 self.yearElements.push(month.yearElement);
5004 self.monthElements.push(month.monthElement);
5005 self.monthNav.appendChild(month.container);
5006 }
5007 self.monthNav.appendChild(self.nextMonthNav);
5008 }
5009 function buildMonthNav() {
5010 self.monthNav = createElement("div", "flatpickr-months");
5011 self.yearElements = [];
5012 self.monthElements = [];
5013 self.prevMonthNav = createElement("span", "flatpickr-prev-month");
5014 self.prevMonthNav.innerHTML = self.config.prevArrow;
5015 self.nextMonthNav = createElement("span", "flatpickr-next-month");
5016 self.nextMonthNav.innerHTML = self.config.nextArrow;
5017 buildMonths();
5018 Object.defineProperty(self, "_hidePrevMonthArrow", {
5019 get: function () { return self.__hidePrevMonthArrow; },
5020 set: function (bool) {
5021 if (self.__hidePrevMonthArrow !== bool) {
5022 toggleClass(self.prevMonthNav, "disabled", bool);
5023 self.__hidePrevMonthArrow = bool;
5024 }
5025 }
5026 });
5027 Object.defineProperty(self, "_hideNextMonthArrow", {
5028 get: function () { return self.__hideNextMonthArrow; },
5029 set: function (bool) {
5030 if (self.__hideNextMonthArrow !== bool) {
5031 toggleClass(self.nextMonthNav, "disabled", bool);
5032 self.__hideNextMonthArrow = bool;
5033 }
5034 }
5035 });
5036 self.currentYearElement = self.yearElements[0];
5037 updateNavigationCurrentMonth();
5038 return self.monthNav;
5039 }
5040 function buildTime() {
5041 self.calendarContainer.classList.add("hasTime");
5042 if (self.config.noCalendar)
5043 self.calendarContainer.classList.add("noCalendar");
5044 self.timeContainer = createElement("div", "flatpickr-time");
5045 self.timeContainer.tabIndex = -1;
5046 var separator = createElement("span", "flatpickr-time-separator", ":");
5047 var hourInput = createNumberInput("flatpickr-hour");
5048 self.hourElement = hourInput.getElementsByTagName("input")[0];
5049 var minuteInput = createNumberInput("flatpickr-minute");
5050 self.minuteElement = minuteInput.getElementsByTagName("input")[0];
5051 self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;
5052 self.hourElement.value = pad(self.latestSelectedDateObj
5053 ? self.latestSelectedDateObj.getHours()
5054 : self.config.time_24hr
5055 ? self.config.defaultHour
5056 : military2ampm(self.config.defaultHour));
5057 self.minuteElement.value = pad(self.latestSelectedDateObj
5058 ? self.latestSelectedDateObj.getMinutes()
5059 : self.config.defaultMinute);
5060 self.hourElement.setAttribute("step", self.config.hourIncrement.toString());
5061 self.minuteElement.setAttribute("step", self.config.minuteIncrement.toString());
5062 self.hourElement.setAttribute("min", self.config.time_24hr ? "0" : "1");
5063 self.hourElement.setAttribute("max", self.config.time_24hr ? "23" : "12");
5064 self.minuteElement.setAttribute("min", "0");
5065 self.minuteElement.setAttribute("max", "59");
5066 self.timeContainer.appendChild(hourInput);
5067 self.timeContainer.appendChild(separator);
5068 self.timeContainer.appendChild(minuteInput);
5069 if (self.config.time_24hr)
5070 self.timeContainer.classList.add("time24hr");
5071 if (self.config.enableSeconds) {
5072 self.timeContainer.classList.add("hasSeconds");
5073 var secondInput = createNumberInput("flatpickr-second");
5074 self.secondElement = secondInput.getElementsByTagName("input")[0];
5075 self.secondElement.value = pad(self.latestSelectedDateObj
5076 ? self.latestSelectedDateObj.getSeconds()
5077 : self.config.defaultSeconds);
5078 self.secondElement.setAttribute("step", self.minuteElement.getAttribute("step"));
5079 self.secondElement.setAttribute("min", "0");
5080 self.secondElement.setAttribute("max", "59");
5081 self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
5082 self.timeContainer.appendChild(secondInput);
5083 }
5084 if (!self.config.time_24hr) {
5085 // add self.amPM if appropriate
5086 self.amPM = createElement("span", "flatpickr-am-pm", self.l10n.amPM[int((self.latestSelectedDateObj
5087 ? self.hourElement.value
5088 : self.config.defaultHour) > 11)]);
5089 self.amPM.title = self.l10n.toggleTitle;
5090 self.amPM.tabIndex = -1;
5091 self.timeContainer.appendChild(self.amPM);
5092 }
5093 return self.timeContainer;
5094 }
5095 function buildWeekdays() {
5096 if (!self.weekdayContainer)
5097 self.weekdayContainer = createElement("div", "flatpickr-weekdays");
5098 else
5099 clearNode(self.weekdayContainer);
5100 for (var i = self.config.showMonths; i--;) {
5101 var container = createElement("div", "flatpickr-weekdaycontainer");
5102 self.weekdayContainer.appendChild(container);
5103 }
5104 updateWeekdays();
5105 return self.weekdayContainer;
5106 }
5107 function updateWeekdays() {
5108 var firstDayOfWeek = self.l10n.firstDayOfWeek;
5109 var weekdays = self.l10n.weekdays.shorthand.slice();
5110 if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
5111 weekdays = weekdays.splice(firstDayOfWeek, weekdays.length).concat(weekdays.splice(0, firstDayOfWeek));
5112 }
5113 for (var i = self.config.showMonths; i--;) {
5114 self.weekdayContainer.children[i].innerHTML = "\n <span class='flatpickr-weekday'>\n " + weekdays.join("</span><span class='flatpickr-weekday'>") + "\n </span>\n ";
5115 }
5116 }
5117 /* istanbul ignore next */
5118 function buildWeeks() {
5119 self.calendarContainer.classList.add("hasWeeks");
5120 var weekWrapper = createElement("div", "flatpickr-weekwrapper");
5121 weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
5122 var weekNumbers = createElement("div", "flatpickr-weeks");
5123 weekWrapper.appendChild(weekNumbers);
5124 return {
5125 weekWrapper: weekWrapper,
5126 weekNumbers: weekNumbers
5127 };
5128 }
5129 function changeMonth(value, is_offset) {
5130 if (is_offset === void 0) { is_offset = true; }
5131 var delta = is_offset ? value : value - self.currentMonth;
5132 if ((delta < 0 && self._hidePrevMonthArrow === true) ||
5133 (delta > 0 && self._hideNextMonthArrow === true))
5134 return;
5135 self.currentMonth += delta;
5136 if (self.currentMonth < 0 || self.currentMonth > 11) {
5137 self.currentYear += self.currentMonth > 11 ? 1 : -1;
5138 self.currentMonth = (self.currentMonth + 12) % 12;
5139 triggerEvent("onYearChange");
5140 }
5141 buildDays();
5142 triggerEvent("onMonthChange");
5143 updateNavigationCurrentMonth();
5144 }
5145 function clear(triggerChangeEvent, toInitial) {
5146 if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }
5147 if (toInitial === void 0) { toInitial = true; }
5148 self.input.value = "";
5149 if (self.altInput !== undefined)
5150 self.altInput.value = "";
5151 if (self.mobileInput !== undefined)
5152 self.mobileInput.value = "";
5153 self.selectedDates = [];
5154 self.latestSelectedDateObj = undefined;
5155 if (toInitial === true) {
5156 self.currentYear = self._initialDate.getFullYear();
5157 self.currentMonth = self._initialDate.getMonth();
5158 }
5159 self.showTimeInput = false;
5160 if (self.config.enableTime === true) {
5161 setDefaultHours();
5162 }
5163 self.redraw();
5164 if (triggerChangeEvent)
5165 // triggerChangeEvent is true (default) or an Event
5166 triggerEvent("onChange");
5167 }
5168 function close() {
5169 self.isOpen = false;
5170 if (!self.isMobile) {
5171 if (self.calendarContainer !== undefined) {
5172 self.calendarContainer.classList.remove("open");
5173 }
5174 if (self._input !== undefined) {
5175 self._input.classList.remove("active");
5176 }
5177 }
5178 triggerEvent("onClose");
5179 }
5180 function destroy() {
5181 if (self.config !== undefined)
5182 triggerEvent("onDestroy");
5183 for (var i = self._handlers.length; i--;) {
5184 var h = self._handlers[i];
5185 h.element.removeEventListener(h.event, h.handler, h.options);
5186 }
5187 self._handlers = [];
5188 if (self.mobileInput) {
5189 if (self.mobileInput.parentNode)
5190 self.mobileInput.parentNode.removeChild(self.mobileInput);
5191 self.mobileInput = undefined;
5192 }
5193 else if (self.calendarContainer && self.calendarContainer.parentNode) {
5194 if (self.config.static && self.calendarContainer.parentNode) {
5195 var wrapper = self.calendarContainer.parentNode;
5196 wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);
5197 if (wrapper.parentNode) {
5198 while (wrapper.firstChild)
5199 wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);
5200 wrapper.parentNode.removeChild(wrapper);
5201 }
5202 }
5203 else
5204 self.calendarContainer.parentNode.removeChild(self.calendarContainer);
5205 }
5206 if (self.altInput) {
5207 self.input.type = "text";
5208 if (self.altInput.parentNode)
5209 self.altInput.parentNode.removeChild(self.altInput);
5210 delete self.altInput;
5211 }
5212 if (self.input) {
5213 self.input.type = self.input._type;
5214 self.input.classList.remove("flatpickr-input");
5215 self.input.removeAttribute("readonly");
5216 self.input.value = "";
5217 }
5218 [
5219 "_showTimeInput",
5220 "latestSelectedDateObj",
5221 "_hideNextMonthArrow",
5222 "_hidePrevMonthArrow",
5223 "__hideNextMonthArrow",
5224 "__hidePrevMonthArrow",
5225 "isMobile",
5226 "isOpen",
5227 "selectedDateElem",
5228 "minDateHasTime",
5229 "maxDateHasTime",
5230 "days",
5231 "daysContainer",
5232 "_input",
5233 "_positionElement",
5234 "innerContainer",
5235 "rContainer",
5236 "monthNav",
5237 "todayDateElem",
5238 "calendarContainer",
5239 "weekdayContainer",
5240 "prevMonthNav",
5241 "nextMonthNav",
5242 "currentMonthElement",
5243 "currentYearElement",
5244 "navigationCurrentMonth",
5245 "selectedDateElem",
5246 "config",
5247 ].forEach(function (k) {
5248 try {
5249 delete self[k];
5250 }
5251 catch (_) { }
5252 });
5253 }
5254 function isCalendarElem(elem) {
5255 if (self.config.appendTo && self.config.appendTo.contains(elem))
5256 return true;
5257 return self.calendarContainer.contains(elem);
5258 }
5259 function documentClick(e) {
5260 if (self.isOpen && !self.config.inline) {
5261 var eventTarget_1 = getEventTarget(e);
5262 var isCalendarElement = isCalendarElem(eventTarget_1);
5263 var isInput = eventTarget_1 === self.input ||
5264 eventTarget_1 === self.altInput ||
5265 self.element.contains(eventTarget_1) ||
5266 // web components
5267 // e.path is not present in all browsers. circumventing typechecks
5268 (e.path &&
5269 e.path.indexOf &&
5270 (~e.path.indexOf(self.input) ||
5271 ~e.path.indexOf(self.altInput)));
5272 var lostFocus = e.type === "blur"
5273 ? isInput &&
5274 e.relatedTarget &&
5275 !isCalendarElem(e.relatedTarget)
5276 : !isInput &&
5277 !isCalendarElement &&
5278 !isCalendarElem(e.relatedTarget);
5279 var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {
5280 return elem.contains(eventTarget_1);
5281 });
5282 if (lostFocus && isIgnored) {
5283 self.close();
5284 if (self.config.mode === "range" && self.selectedDates.length === 1) {
5285 self.clear(false);
5286 self.redraw();
5287 }
5288 }
5289 }
5290 }
5291 function changeYear(newYear) {
5292 if (!newYear ||
5293 (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||
5294 (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))
5295 return;
5296 var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;
5297 self.currentYear = newYearNum || self.currentYear;
5298 if (self.config.maxDate &&
5299 self.currentYear === self.config.maxDate.getFullYear()) {
5300 self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
5301 }
5302 else if (self.config.minDate &&
5303 self.currentYear === self.config.minDate.getFullYear()) {
5304 self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
5305 }
5306 if (isNewYear) {
5307 self.redraw();
5308 triggerEvent("onYearChange");
5309 }
5310 }
5311 function isEnabled(date, timeless) {
5312 if (timeless === void 0) { timeless = true; }
5313 var dateToCheck = self.parseDate(date, undefined, timeless); // timeless
5314 if ((self.config.minDate &&
5315 dateToCheck &&
5316 compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||
5317 (self.config.maxDate &&
5318 dateToCheck &&
5319 compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))
5320 return false;
5321 if (self.config.enable.length === 0 && self.config.disable.length === 0)
5322 return true;
5323 if (dateToCheck === undefined)
5324 return false;
5325 var bool = self.config.enable.length > 0, array = bool ? self.config.enable : self.config.disable;
5326 for (var i = 0, d = void 0; i < array.length; i++) {
5327 d = array[i];
5328 if (typeof d === "function" &&
5329 d(dateToCheck) // disabled by function
5330 )
5331 return bool;
5332 else if (d instanceof Date &&
5333 dateToCheck !== undefined &&
5334 d.getTime() === dateToCheck.getTime())
5335 // disabled by date
5336 return bool;
5337 else if (typeof d === "string" && dateToCheck !== undefined) {
5338 // disabled by date string
5339 var parsed = self.parseDate(d, undefined, true);
5340 return parsed && parsed.getTime() === dateToCheck.getTime()
5341 ? bool
5342 : !bool;
5343 }
5344 else if (
5345 // disabled by range
5346 typeof d === "object" &&
5347 dateToCheck !== undefined &&
5348 d.from &&
5349 d.to &&
5350 dateToCheck.getTime() >= d.from.getTime() &&
5351 dateToCheck.getTime() <= d.to.getTime())
5352 return bool;
5353 }
5354 return !bool;
5355 }
5356 function isInView(elem) {
5357 if (self.daysContainer !== undefined)
5358 return (elem.className.indexOf("hidden") === -1 &&
5359 self.daysContainer.contains(elem));
5360 return false;
5361 }
5362 function onKeyDown(e) {
5363 // e.key e.keyCode
5364 // "Backspace" 8
5365 // "Tab" 9
5366 // "Enter" 13
5367 // "Escape" (IE "Esc") 27
5368 // "ArrowLeft" (IE "Left") 37
5369 // "ArrowUp" (IE "Up") 38
5370 // "ArrowRight" (IE "Right") 39
5371 // "ArrowDown" (IE "Down") 40
5372 // "Delete" (IE "Del") 46
5373 var isInput = e.target === self._input;
5374 var allowInput = self.config.allowInput;
5375 var allowKeydown = self.isOpen && (!allowInput || !isInput);
5376 var allowInlineKeydown = self.config.inline && isInput && !allowInput;
5377 if (e.keyCode === 13 && isInput) {
5378 if (allowInput) {
5379 self.setDate(self._input.value, true, e.target === self.altInput
5380 ? self.config.altFormat
5381 : self.config.dateFormat);
5382 return e.target.blur();
5383 }
5384 else
5385 self.open();
5386 }
5387 else if (isCalendarElem(e.target) ||
5388 allowKeydown ||
5389 allowInlineKeydown) {
5390 var isTimeObj = !!self.timeContainer &&
5391 self.timeContainer.contains(e.target);
5392 switch (e.keyCode) {
5393 case 13:
5394 if (isTimeObj) {
5395 updateTime();
5396 focusAndClose();
5397 }
5398 else
5399 selectDate(e);
5400 break;
5401 case 27: // escape
5402 e.preventDefault();
5403 focusAndClose();
5404 break;
5405 case 8:
5406 case 46:
5407 if (isInput && !self.config.allowInput) {
5408 e.preventDefault();
5409 self.clear();
5410 }
5411 break;
5412 case 37:
5413 case 39:
5414 if (!isTimeObj) {
5415 e.preventDefault();
5416 if (self.daysContainer !== undefined &&
5417 (allowInput === false ||
5418 (document.activeElement && isInView(document.activeElement)))) {
5419 var delta_1 = e.keyCode === 39 ? 1 : -1;
5420 if (!e.ctrlKey)
5421 focusOnDay(undefined, delta_1);
5422 else {
5423 e.stopPropagation();
5424 changeMonth(delta_1);
5425 focusOnDay(getFirstAvailableDay(1), 0);
5426 }
5427 }
5428 }
5429 else if (self.hourElement)
5430 self.hourElement.focus();
5431 break;
5432 case 38:
5433 case 40:
5434 e.preventDefault();
5435 var delta = e.keyCode === 40 ? 1 : -1;
5436 if ((self.daysContainer && e.target.$i !== undefined) ||
5437 e.target === self.input) {
5438 if (e.ctrlKey) {
5439 e.stopPropagation();
5440 changeYear(self.currentYear - delta);
5441 focusOnDay(getFirstAvailableDay(1), 0);
5442 }
5443 else if (!isTimeObj)
5444 focusOnDay(undefined, delta * 7);
5445 }
5446 else if (self.config.enableTime) {
5447 if (!isTimeObj && self.hourElement)
5448 self.hourElement.focus();
5449 updateTime(e);
5450 self._debouncedChange();
5451 }
5452 break;
5453 case 9:
5454 if (isTimeObj) {
5455 var elems = [
5456 self.hourElement,
5457 self.minuteElement,
5458 self.secondElement,
5459 self.amPM,
5460 ].filter(function (x) { return x; });
5461 var i = elems.indexOf(e.target);
5462 if (i !== -1) {
5463 var target = elems[i + (e.shiftKey ? -1 : 1)];
5464 if (target !== undefined) {
5465 e.preventDefault();
5466 target.focus();
5467 }
5468 else if (e.shiftKey) {
5469 e.preventDefault();
5470 self._input.focus();
5471 }
5472 }
5473 }
5474 break;
5475 default:
5476 break;
5477 }
5478 }
5479 if (self.amPM !== undefined && e.target === self.amPM) {
5480 switch (e.key) {
5481 case self.l10n.amPM[0].charAt(0):
5482 case self.l10n.amPM[0].charAt(0).toLowerCase():
5483 self.amPM.textContent = self.l10n.amPM[0];
5484 setHoursFromInputs();
5485 updateValue();
5486 break;
5487 case self.l10n.amPM[1].charAt(0):
5488 case self.l10n.amPM[1].charAt(0).toLowerCase():
5489 self.amPM.textContent = self.l10n.amPM[1];
5490 setHoursFromInputs();
5491 updateValue();
5492 break;
5493 }
5494 }
5495 triggerEvent("onKeyDown", e);
5496 }
5497 function onMouseOver(elem) {
5498 if (self.selectedDates.length !== 1 ||
5499 (elem &&
5500 (!elem.classList.contains("flatpickr-day") ||
5501 elem.classList.contains("disabled"))))
5502 return;
5503 var hoverDate = elem
5504 ? elem.dateObj.getTime()
5505 : self.days.firstElementChild.dateObj.getTime(), initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime()), lastDate = self.daysContainer.lastChild
5506 .lastChild.dateObj.getTime();
5507 var containsDisabled = false;
5508 var minRange = 0, maxRange = 0;
5509 for (var t = rangeStartDate; t < lastDate; t += duration.DAY) {
5510 if (!isEnabled(new Date(t), true)) {
5511 containsDisabled =
5512 containsDisabled || (t > rangeStartDate && t < rangeEndDate);
5513 if (t < initialDate && (!minRange || t > minRange))
5514 minRange = t;
5515 else if (t > initialDate && (!maxRange || t < maxRange))
5516 maxRange = t;
5517 }
5518 }
5519 for (var m = 0; m < self.config.showMonths; m++) {
5520 var month = self.daysContainer.children[m];
5521 var prevMonth = self.daysContainer.children[m - 1];
5522 var _loop_1 = function (i, l) {
5523 var dayElem = month.children[i], date = dayElem.dateObj;
5524 var timestamp = date.getTime();
5525 var outOfRange = (minRange > 0 && timestamp < minRange) ||
5526 (maxRange > 0 && timestamp > maxRange);
5527 if (outOfRange) {
5528 dayElem.classList.add("notAllowed");
5529 ["inRange", "startRange", "endRange"].forEach(function (c) {
5530 dayElem.classList.remove(c);
5531 });
5532 return "continue";
5533 }
5534 else if (containsDisabled && !outOfRange)
5535 return "continue";
5536 ["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) {
5537 dayElem.classList.remove(c);
5538 });
5539 if (elem !== undefined) {
5540 elem.classList.add(hoverDate < self.selectedDates[0].getTime()
5541 ? "startRange"
5542 : "endRange");
5543 if (month.contains(elem) ||
5544 !(m > 0 &&
5545 prevMonth &&
5546 prevMonth.lastChild.dateObj.getTime() >= timestamp)) {
5547 if (initialDate < hoverDate && timestamp === initialDate)
5548 dayElem.classList.add("startRange");
5549 else if (initialDate > hoverDate && timestamp === initialDate)
5550 dayElem.classList.add("endRange");
5551 if (timestamp >= minRange &&
5552 (maxRange === 0 || timestamp <= maxRange) &&
5553 isBetween(timestamp, initialDate, hoverDate))
5554 dayElem.classList.add("inRange");
5555 }
5556 }
5557 };
5558 for (var i = 0, l = month.children.length; i < l; i++) {
5559 _loop_1(i, l);
5560 }
5561 }
5562 }
5563 function onResize() {
5564 if (self.isOpen && !self.config.static && !self.config.inline)
5565 positionCalendar();
5566 }
5567 function setDefaultTime() {
5568 self.setDate(self.config.minDate !== undefined
5569 ? new Date(self.config.minDate.getTime())
5570 : new Date(), false);
5571 setDefaultHours();
5572 updateValue();
5573 }
5574 function open(e, positionElement) {
5575 if (positionElement === void 0) { positionElement = self._positionElement; }
5576 if (self.isMobile === true) {
5577 if (e) {
5578 e.preventDefault();
5579 e.target && e.target.blur();
5580 }
5581 if (self.mobileInput !== undefined) {
5582 self.mobileInput.focus();
5583 self.mobileInput.click();
5584 }
5585 triggerEvent("onOpen");
5586 return;
5587 }
5588 if (self._input.disabled || self.config.inline)
5589 return;
5590 var wasOpen = self.isOpen;
5591 self.isOpen = true;
5592 if (!wasOpen) {
5593 self.calendarContainer.classList.add("open");
5594 self._input.classList.add("active");
5595 triggerEvent("onOpen");
5596 positionCalendar(positionElement);
5597 }
5598 if (self.config.enableTime === true && self.config.noCalendar === true) {
5599 if (self.selectedDates.length === 0) {
5600 setDefaultTime();
5601 }
5602 if (self.config.allowInput === false &&
5603 (e === undefined ||
5604 !self.timeContainer.contains(e.relatedTarget))) {
5605 setTimeout(function () { return self.hourElement.select(); }, 50);
5606 }
5607 }
5608 }
5609 function minMaxDateSetter(type) {
5610 return function (date) {
5611 var dateObj = (self.config["_" + type + "Date"] = self.parseDate(date, self.config.dateFormat));
5612 var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
5613 if (dateObj !== undefined) {
5614 self[type === "min" ? "minDateHasTime" : "maxDateHasTime"] =
5615 dateObj.getHours() > 0 ||
5616 dateObj.getMinutes() > 0 ||
5617 dateObj.getSeconds() > 0;
5618 }
5619 if (self.selectedDates) {
5620 self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });
5621 if (!self.selectedDates.length && type === "min")
5622 setHoursFromDate(dateObj);
5623 updateValue();
5624 }
5625 if (self.daysContainer) {
5626 redraw();
5627 if (dateObj !== undefined)
5628 self.currentYearElement[type] = dateObj.getFullYear().toString();
5629 else
5630 self.currentYearElement.removeAttribute(type);
5631 self.currentYearElement.disabled =
5632 !!inverseDateObj &&
5633 dateObj !== undefined &&
5634 inverseDateObj.getFullYear() === dateObj.getFullYear();
5635 }
5636 };
5637 }
5638 function parseConfig() {
5639 var boolOpts = [
5640 "wrap",
5641 "weekNumbers",
5642 "allowInput",
5643 "clickOpens",
5644 "time_24hr",
5645 "enableTime",
5646 "noCalendar",
5647 "altInput",
5648 "shorthandCurrentMonth",
5649 "inline",
5650 "static",
5651 "enableSeconds",
5652 "disableMobile",
5653 ];
5654 var userConfig = __assign({}, instanceConfig, JSON.parse(JSON.stringify(element.dataset || {})));
5655 var formats = {};
5656 self.config.parseDate = userConfig.parseDate;
5657 self.config.formatDate = userConfig.formatDate;
5658 Object.defineProperty(self.config, "enable", {
5659 get: function () { return self.config._enable; },
5660 set: function (dates) {
5661 self.config._enable = parseDateRules(dates);
5662 }
5663 });
5664 Object.defineProperty(self.config, "disable", {
5665 get: function () { return self.config._disable; },
5666 set: function (dates) {
5667 self.config._disable = parseDateRules(dates);
5668 }
5669 });
5670 var timeMode = userConfig.mode === "time";
5671 if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {
5672 formats.dateFormat =
5673 userConfig.noCalendar || timeMode
5674 ? "H:i" + (userConfig.enableSeconds ? ":S" : "")
5675 : flatpickr.defaultConfig.dateFormat +
5676 " H:i" +
5677 (userConfig.enableSeconds ? ":S" : "");
5678 }
5679 if (userConfig.altInput &&
5680 (userConfig.enableTime || timeMode) &&
5681 !userConfig.altFormat) {
5682 formats.altFormat =
5683 userConfig.noCalendar || timeMode
5684 ? "h:i" + (userConfig.enableSeconds ? ":S K" : " K")
5685 : flatpickr.defaultConfig.altFormat +
5686 (" h:i" + (userConfig.enableSeconds ? ":S" : "") + " K");
5687 }
5688 Object.defineProperty(self.config, "minDate", {
5689 get: function () { return self.config._minDate; },
5690 set: minMaxDateSetter("min")
5691 });
5692 Object.defineProperty(self.config, "maxDate", {
5693 get: function () { return self.config._maxDate; },
5694 set: minMaxDateSetter("max")
5695 });
5696 var minMaxTimeSetter = function (type) { return function (val) {
5697 self.config[type === "min" ? "_minTime" : "_maxTime"] = self.parseDate(val, "H:i");
5698 }; };
5699 Object.defineProperty(self.config, "minTime", {
5700 get: function () { return self.config._minTime; },
5701 set: minMaxTimeSetter("min")
5702 });
5703 Object.defineProperty(self.config, "maxTime", {
5704 get: function () { return self.config._maxTime; },
5705 set: minMaxTimeSetter("max")
5706 });
5707 if (userConfig.mode === "time") {
5708 self.config.noCalendar = true;
5709 self.config.enableTime = true;
5710 }
5711 Object.assign(self.config, formats, userConfig);
5712 for (var i = 0; i < boolOpts.length; i++)
5713 self.config[boolOpts[i]] =
5714 self.config[boolOpts[i]] === true ||
5715 self.config[boolOpts[i]] === "true";
5716 HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {
5717 self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);
5718 });
5719 self.isMobile =
5720 !self.config.disableMobile &&
5721 !self.config.inline &&
5722 self.config.mode === "single" &&
5723 !self.config.disable.length &&
5724 !self.config.enable.length &&
5725 !self.config.weekNumbers &&
5726 /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
5727 for (var i = 0; i < self.config.plugins.length; i++) {
5728 var pluginConf = self.config.plugins[i](self) || {};
5729 for (var key in pluginConf) {
5730 if (HOOKS.indexOf(key) > -1) {
5731 self.config[key] = arrayify(pluginConf[key])
5732 .map(bindToInstance)
5733 .concat(self.config[key]);
5734 }
5735 else if (typeof userConfig[key] === "undefined")
5736 self.config[key] = pluginConf[key];
5737 }
5738 }
5739 triggerEvent("onParseConfig");
5740 }
5741 function setupLocale() {
5742 if (typeof self.config.locale !== "object" &&
5743 typeof flatpickr.l10ns[self.config.locale] === "undefined")
5744 self.config.errorHandler(new Error("flatpickr: invalid locale " + self.config.locale));
5745 self.l10n = __assign({}, flatpickr.l10ns["default"], (typeof self.config.locale === "object"
5746 ? self.config.locale
5747 : self.config.locale !== "default"
5748 ? flatpickr.l10ns[self.config.locale]
5749 : undefined));
5750 tokenRegex.K = "(" + self.l10n.amPM[0] + "|" + self.l10n.amPM[1] + "|" + self.l10n.amPM[0].toLowerCase() + "|" + self.l10n.amPM[1].toLowerCase() + ")";
5751 self.formatDate = createDateFormatter(self);
5752 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
5753 }
5754 function positionCalendar(customPositionElement) {
5755 if (self.calendarContainer === undefined)
5756 return;
5757 triggerEvent("onPreCalendarPosition");
5758 var positionElement = customPositionElement || self._positionElement;
5759 var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, (function (acc, child) { return acc + child.offsetHeight; }), 0), calendarWidth = self.calendarContainer.offsetWidth, configPos = self.config.position.split(" "), configPosVertical = configPos[0], configPosHorizontal = configPos.length > 1 ? configPos[1] : null, inputBounds = positionElement.getBoundingClientRect(), distanceFromBottom = window.innerHeight - inputBounds.bottom, showOnTop = configPosVertical === "above" ||
5760 (configPosVertical !== "below" &&
5761 distanceFromBottom < calendarHeight &&
5762 inputBounds.top > calendarHeight);
5763 var top = window.pageYOffset +
5764 inputBounds.top +
5765 (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);
5766 toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
5767 toggleClass(self.calendarContainer, "arrowBottom", showOnTop);
5768 if (self.config.inline)
5769 return;
5770 var left = window.pageXOffset +
5771 inputBounds.left -
5772 (configPosHorizontal != null && configPosHorizontal === "center"
5773 ? (calendarWidth - inputBounds.width) / 2
5774 : 0);
5775 var right = window.document.body.offsetWidth - inputBounds.right;
5776 var rightMost = left + calendarWidth > window.document.body.offsetWidth;
5777 var centerMost = right + calendarWidth > window.document.body.offsetWidth;
5778 toggleClass(self.calendarContainer, "rightMost", rightMost);
5779 if (self.config.static)
5780 return;
5781 self.calendarContainer.style.top = top + "px";
5782 if (!rightMost) {
5783 self.calendarContainer.style.left = left + "px";
5784 self.calendarContainer.style.right = "auto";
5785 }
5786 else if (!centerMost) {
5787 self.calendarContainer.style.left = "auto";
5788 self.calendarContainer.style.right = right + "px";
5789 }
5790 else {
5791 var doc = document.styleSheets[0];
5792 // some testing environments don't have css support
5793 if (doc === undefined)
5794 return;
5795 var bodyWidth = window.document.body.offsetWidth;
5796 var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);
5797 var centerBefore = ".flatpickr-calendar.centerMost:before";
5798 var centerAfter = ".flatpickr-calendar.centerMost:after";
5799 var centerIndex = doc.cssRules.length;
5800 var centerStyle = "{left:" + inputBounds.left + "px;right:auto;}";
5801 toggleClass(self.calendarContainer, "rightMost", false);
5802 toggleClass(self.calendarContainer, "centerMost", true);
5803 doc.insertRule(centerBefore + "," + centerAfter + centerStyle, centerIndex);
5804 self.calendarContainer.style.left = centerLeft + "px";
5805 self.calendarContainer.style.right = "auto";
5806 }
5807 }
5808 function redraw() {
5809 if (self.config.noCalendar || self.isMobile)
5810 return;
5811 updateNavigationCurrentMonth();
5812 buildDays();
5813 }
5814 function focusAndClose() {
5815 self._input.focus();
5816 if (window.navigator.userAgent.indexOf("MSIE") !== -1 ||
5817 navigator.msMaxTouchPoints !== undefined) {
5818 // hack - bugs in the way IE handles focus keeps the calendar open
5819 setTimeout(self.close, 0);
5820 }
5821 else {
5822 self.close();
5823 }
5824 }
5825 function selectDate(e) {
5826 e.preventDefault();
5827 e.stopPropagation();
5828 var isSelectable = function (day) {
5829 return day.classList &&
5830 day.classList.contains("flatpickr-day") &&
5831 !day.classList.contains("disabled") &&
5832 !day.classList.contains("notAllowed");
5833 };
5834 var t = findParent(e.target, isSelectable);
5835 if (t === undefined)
5836 return;
5837 var target = t;
5838 var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));
5839 var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||
5840 selectedDate.getMonth() >
5841 self.currentMonth + self.config.showMonths - 1) &&
5842 self.config.mode !== "range";
5843 self.selectedDateElem = target;
5844 if (self.config.mode === "single")
5845 self.selectedDates = [selectedDate];
5846 else if (self.config.mode === "multiple") {
5847 var selectedIndex = isDateSelected(selectedDate);
5848 if (selectedIndex)
5849 self.selectedDates.splice(parseInt(selectedIndex), 1);
5850 else
5851 self.selectedDates.push(selectedDate);
5852 }
5853 else if (self.config.mode === "range") {
5854 if (self.selectedDates.length === 2) {
5855 self.clear(false, false);
5856 }
5857 self.latestSelectedDateObj = selectedDate;
5858 self.selectedDates.push(selectedDate);
5859 // unless selecting same date twice, sort ascendingly
5860 if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)
5861 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
5862 }
5863 setHoursFromInputs();
5864 if (shouldChangeMonth) {
5865 var isNewYear = self.currentYear !== selectedDate.getFullYear();
5866 self.currentYear = selectedDate.getFullYear();
5867 self.currentMonth = selectedDate.getMonth();
5868 if (isNewYear)
5869 triggerEvent("onYearChange");
5870 triggerEvent("onMonthChange");
5871 }
5872 updateNavigationCurrentMonth();
5873 buildDays();
5874 updateValue();
5875 if (self.config.enableTime)
5876 setTimeout(function () { return (self.showTimeInput = true); }, 50);
5877 // maintain focus
5878 if (!shouldChangeMonth &&
5879 self.config.mode !== "range" &&
5880 self.config.showMonths === 1)
5881 focusOnDayElem(target);
5882 else if (self.selectedDateElem !== undefined &&
5883 self.hourElement === undefined) {
5884 self.selectedDateElem && self.selectedDateElem.focus();
5885 }
5886 if (self.hourElement !== undefined)
5887 self.hourElement !== undefined && self.hourElement.focus();
5888 if (self.config.closeOnSelect) {
5889 var single = self.config.mode === "single" && !self.config.enableTime;
5890 var range = self.config.mode === "range" &&
5891 self.selectedDates.length === 2 &&
5892 !self.config.enableTime;
5893 if (single || range) {
5894 focusAndClose();
5895 }
5896 }
5897 triggerChange();
5898 }
5899 var CALLBACKS = {
5900 locale: [setupLocale, updateWeekdays],
5901 showMonths: [buildMonths, setCalendarWidth, buildWeekdays]
5902 };
5903 function set(option, value) {
5904 if (option !== null && typeof option === "object")
5905 Object.assign(self.config, option);
5906 else {
5907 self.config[option] = value;
5908 if (CALLBACKS[option] !== undefined)
5909 CALLBACKS[option].forEach(function (x) { return x(); });
5910 else if (HOOKS.indexOf(option) > -1)
5911 self.config[option] = arrayify(value);
5912 }
5913 self.redraw();
5914 updateValue(false);
5915 }
5916 function setSelectedDate(inputDate, format) {
5917 var dates = [];
5918 if (inputDate instanceof Array)
5919 dates = inputDate.map(function (d) { return self.parseDate(d, format); });
5920 else if (inputDate instanceof Date || typeof inputDate === "number")
5921 dates = [self.parseDate(inputDate, format)];
5922 else if (typeof inputDate === "string") {
5923 switch (self.config.mode) {
5924 case "single":
5925 case "time":
5926 dates = [self.parseDate(inputDate, format)];
5927 break;
5928 case "multiple":
5929 dates = inputDate
5930 .split(self.config.conjunction)
5931 .map(function (date) { return self.parseDate(date, format); });
5932 break;
5933 case "range":
5934 dates = inputDate
5935 .split(self.l10n.rangeSeparator)
5936 .map(function (date) { return self.parseDate(date, format); });
5937 break;
5938 default:
5939 break;
5940 }
5941 }
5942 else
5943 self.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(inputDate)));
5944 self.selectedDates = dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); });
5945 if (self.config.mode === "range")
5946 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
5947 }
5948 function setDate(date, triggerChange, format) {
5949 if (triggerChange === void 0) { triggerChange = false; }
5950 if (format === void 0) { format = self.config.dateFormat; }
5951 if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))
5952 return self.clear(triggerChange);
5953 setSelectedDate(date, format);
5954 self.showTimeInput = self.selectedDates.length > 0;
5955 self.latestSelectedDateObj = self.selectedDates[0];
5956 self.redraw();
5957 jumpToDate();
5958 setHoursFromDate();
5959 updateValue(triggerChange);
5960 if (triggerChange)
5961 triggerEvent("onChange");
5962 }
5963 function parseDateRules(arr) {
5964 return arr
5965 .slice()
5966 .map(function (rule) {
5967 if (typeof rule === "string" ||
5968 typeof rule === "number" ||
5969 rule instanceof Date) {
5970 return self.parseDate(rule, undefined, true);
5971 }
5972 else if (rule &&
5973 typeof rule === "object" &&
5974 rule.from &&
5975 rule.to)
5976 return {
5977 from: self.parseDate(rule.from, undefined),
5978 to: self.parseDate(rule.to, undefined)
5979 };
5980 return rule;
5981 })
5982 .filter(function (x) { return x; }); // remove falsy values
5983 }
5984 function setupDates() {
5985 self.selectedDates = [];
5986 self.now = self.parseDate(self.config.now) || new Date();
5987 // Workaround IE11 setting placeholder as the input's value
5988 var preloadedDate = self.config.defaultDate ||
5989 ((self.input.nodeName === "INPUT" ||
5990 self.input.nodeName === "TEXTAREA") &&
5991 self.input.placeholder &&
5992 self.input.value === self.input.placeholder
5993 ? null
5994 : self.input.value);
5995 if (preloadedDate)
5996 setSelectedDate(preloadedDate, self.config.dateFormat);
5997 self._initialDate =
5998 self.selectedDates.length > 0
5999 ? self.selectedDates[0]
6000 : self.config.minDate &&
6001 self.config.minDate.getTime() > self.now.getTime()
6002 ? self.config.minDate
6003 : self.config.maxDate &&
6004 self.config.maxDate.getTime() < self.now.getTime()
6005 ? self.config.maxDate
6006 : self.now;
6007 self.currentYear = self._initialDate.getFullYear();
6008 self.currentMonth = self._initialDate.getMonth();
6009 if (self.selectedDates.length > 0)
6010 self.latestSelectedDateObj = self.selectedDates[0];
6011 if (self.config.minTime !== undefined)
6012 self.config.minTime = self.parseDate(self.config.minTime, "H:i");
6013 if (self.config.maxTime !== undefined)
6014 self.config.maxTime = self.parseDate(self.config.maxTime, "H:i");
6015 self.minDateHasTime =
6016 !!self.config.minDate &&
6017 (self.config.minDate.getHours() > 0 ||
6018 self.config.minDate.getMinutes() > 0 ||
6019 self.config.minDate.getSeconds() > 0);
6020 self.maxDateHasTime =
6021 !!self.config.maxDate &&
6022 (self.config.maxDate.getHours() > 0 ||
6023 self.config.maxDate.getMinutes() > 0 ||
6024 self.config.maxDate.getSeconds() > 0);
6025 Object.defineProperty(self, "showTimeInput", {
6026 get: function () { return self._showTimeInput; },
6027 set: function (bool) {
6028 self._showTimeInput = bool;
6029 if (self.calendarContainer)
6030 toggleClass(self.calendarContainer, "showTimeInput", bool);
6031 self.isOpen && positionCalendar();
6032 }
6033 });
6034 }
6035 function setupInputs() {
6036 self.input = self.config.wrap
6037 ? element.querySelector("[data-input]")
6038 : element;
6039 /* istanbul ignore next */
6040 if (!self.input) {
6041 self.config.errorHandler(new Error("Invalid input element specified"));
6042 return;
6043 }
6044 // hack: store previous type to restore it after destroy()
6045 self.input._type = self.input.type;
6046 self.input.type = "text";
6047 self.input.classList.add("flatpickr-input");
6048 self._input = self.input;
6049 if (self.config.altInput) {
6050 // replicate self.element
6051 self.altInput = createElement(self.input.nodeName, self.input.className + " " + self.config.altInputClass);
6052 self._input = self.altInput;
6053 self.altInput.placeholder = self.input.placeholder;
6054 self.altInput.disabled = self.input.disabled;
6055 self.altInput.required = self.input.required;
6056 self.altInput.tabIndex = self.input.tabIndex;
6057 self.altInput.type = "text";
6058 self.input.setAttribute("type", "hidden");
6059 if (!self.config.static && self.input.parentNode)
6060 self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
6061 }
6062 if (!self.config.allowInput)
6063 self._input.setAttribute("readonly", "readonly");
6064 self._positionElement = self.config.positionElement || self._input;
6065 }
6066 function setupMobile() {
6067 var inputType = self.config.enableTime
6068 ? self.config.noCalendar
6069 ? "time"
6070 : "datetime-local"
6071 : "date";
6072 self.mobileInput = createElement("input", self.input.className + " flatpickr-mobile");
6073 self.mobileInput.step = self.input.getAttribute("step") || "any";
6074 self.mobileInput.tabIndex = 1;
6075 self.mobileInput.type = inputType;
6076 self.mobileInput.disabled = self.input.disabled;
6077 self.mobileInput.required = self.input.required;
6078 self.mobileInput.placeholder = self.input.placeholder;
6079 self.mobileFormatStr =
6080 inputType === "datetime-local"
6081 ? "Y-m-d\\TH:i:S"
6082 : inputType === "date"
6083 ? "Y-m-d"
6084 : "H:i:S";
6085 if (self.selectedDates.length > 0) {
6086 self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);
6087 }
6088 if (self.config.minDate)
6089 self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");
6090 if (self.config.maxDate)
6091 self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");
6092 self.input.type = "hidden";
6093 if (self.altInput !== undefined)
6094 self.altInput.type = "hidden";
6095 try {
6096 if (self.input.parentNode)
6097 self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
6098 }
6099 catch (_a) { }
6100 bind(self.mobileInput, "change", function (e) {
6101 self.setDate(e.target.value, false, self.mobileFormatStr);
6102 triggerEvent("onChange");
6103 triggerEvent("onClose");
6104 });
6105 }
6106 function toggle(e) {
6107 if (self.isOpen === true)
6108 return self.close();
6109 self.open(e);
6110 }
6111 function triggerEvent(event, data) {
6112 // If the instance has been destroyed already, all hooks have been removed
6113 if (self.config === undefined)
6114 return;
6115 var hooks = self.config[event];
6116 if (hooks !== undefined && hooks.length > 0) {
6117 for (var i = 0; hooks[i] && i < hooks.length; i++)
6118 hooks[i](self.selectedDates, self.input.value, self, data);
6119 }
6120 if (event === "onChange") {
6121 self.input.dispatchEvent(createEvent("change"));
6122 // many front-end frameworks bind to the input event
6123 self.input.dispatchEvent(createEvent("input"));
6124 }
6125 }
6126 function createEvent(name) {
6127 var e = document.createEvent("Event");
6128 e.initEvent(name, true, true);
6129 return e;
6130 }
6131 function isDateSelected(date) {
6132 for (var i = 0; i < self.selectedDates.length; i++) {
6133 if (compareDates(self.selectedDates[i], date) === 0)
6134 return "" + i;
6135 }
6136 return false;
6137 }
6138 function isDateInRange(date) {
6139 if (self.config.mode !== "range" || self.selectedDates.length < 2)
6140 return false;
6141 return (compareDates(date, self.selectedDates[0]) >= 0 &&
6142 compareDates(date, self.selectedDates[1]) <= 0);
6143 }
6144 function updateNavigationCurrentMonth() {
6145 if (self.config.noCalendar || self.isMobile || !self.monthNav)
6146 return;
6147 self.yearElements.forEach(function (yearElement, i) {
6148 var d = new Date(self.currentYear, self.currentMonth, 1);
6149 d.setMonth(self.currentMonth + i);
6150 self.monthElements[i].textContent =
6151 monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) +
6152 " ";
6153 yearElement.value = d.getFullYear().toString();
6154 });
6155 self._hidePrevMonthArrow =
6156 self.config.minDate !== undefined &&
6157 (self.currentYear === self.config.minDate.getFullYear()
6158 ? self.currentMonth <= self.config.minDate.getMonth()
6159 : self.currentYear < self.config.minDate.getFullYear());
6160 self._hideNextMonthArrow =
6161 self.config.maxDate !== undefined &&
6162 (self.currentYear === self.config.maxDate.getFullYear()
6163 ? self.currentMonth + 1 > self.config.maxDate.getMonth()
6164 : self.currentYear > self.config.maxDate.getFullYear());
6165 }
6166 function getDateStr(format) {
6167 return self.selectedDates
6168 .map(function (dObj) { return self.formatDate(dObj, format); })
6169 .filter(function (d, i, arr) {
6170 return self.config.mode !== "range" ||
6171 self.config.enableTime ||
6172 arr.indexOf(d) === i;
6173 })
6174 .join(self.config.mode !== "range"
6175 ? self.config.conjunction
6176 : self.l10n.rangeSeparator);
6177 }
6178 /**
6179 * Updates the values of inputs associated with the calendar
6180 */
6181 function updateValue(triggerChange) {
6182 if (triggerChange === void 0) { triggerChange = true; }
6183 if (self.selectedDates.length === 0)
6184 return self.clear(triggerChange);
6185 if (self.mobileInput !== undefined && self.mobileFormatStr) {
6186 self.mobileInput.value =
6187 self.latestSelectedDateObj !== undefined
6188 ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)
6189 : "";
6190 }
6191 self.input.value = getDateStr(self.config.dateFormat);
6192 if (self.altInput !== undefined) {
6193 self.altInput.value = getDateStr(self.config.altFormat);
6194 }
6195 if (triggerChange !== false)
6196 triggerEvent("onValueUpdate");
6197 }
6198 function onMonthNavClick(e) {
6199 e.preventDefault();
6200 var isPrevMonth = self.prevMonthNav.contains(e.target);
6201 var isNextMonth = self.nextMonthNav.contains(e.target);
6202 if (isPrevMonth || isNextMonth) {
6203 changeMonth(isPrevMonth ? -1 : 1);
6204 }
6205 else if (self.yearElements.indexOf(e.target) >= 0) {
6206 e.target.select();
6207 }
6208 else if (e.target.classList.contains("arrowUp")) {
6209 self.changeYear(self.currentYear + 1);
6210 }
6211 else if (e.target.classList.contains("arrowDown")) {
6212 self.changeYear(self.currentYear - 1);
6213 }
6214 }
6215 function timeWrapper(e) {
6216 e.preventDefault();
6217 var isKeyDown = e.type === "keydown", input = e.target;
6218 if (self.amPM !== undefined && e.target === self.amPM) {
6219 self.amPM.textContent =
6220 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
6221 }
6222 var min = parseFloat(input.getAttribute("min")), max = parseFloat(input.getAttribute("max")), step = parseFloat(input.getAttribute("step")), curValue = parseInt(input.value, 10), delta = e.delta ||
6223 (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);
6224 var newValue = curValue + step * delta;
6225 if (typeof input.value !== "undefined" && input.value.length === 2) {
6226 var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;
6227 if (newValue < min) {
6228 newValue =
6229 max +
6230 newValue +
6231 int(!isHourElem) +
6232 (int(isHourElem) && int(!self.amPM));
6233 if (isMinuteElem)
6234 incrementNumInput(undefined, -1, self.hourElement);
6235 }
6236 else if (newValue > max) {
6237 newValue =
6238 input === self.hourElement ? newValue - max - int(!self.amPM) : min;
6239 if (isMinuteElem)
6240 incrementNumInput(undefined, 1, self.hourElement);
6241 }
6242 if (self.amPM &&
6243 isHourElem &&
6244 (step === 1
6245 ? newValue + curValue === 23
6246 : Math.abs(newValue - curValue) > step)) {
6247 self.amPM.textContent =
6248 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
6249 }
6250 input.value = pad(newValue);
6251 }
6252 }
6253 init();
6254 return self;
6255 }
6256 /* istanbul ignore next */
6257 function _flatpickr(nodeList, config) {
6258 // static list
6259 var nodes = Array.prototype.slice
6260 .call(nodeList)
6261 .filter(function (x) { return x instanceof HTMLElement; });
6262 var instances = [];
6263 for (var i = 0; i < nodes.length; i++) {
6264 var node = nodes[i];
6265 try {
6266 if (node.getAttribute("data-fp-omit") !== null)
6267 continue;
6268 if (node._flatpickr !== undefined) {
6269 node._flatpickr.destroy();
6270 node._flatpickr = undefined;
6271 }
6272 node._flatpickr = FlatpickrInstance(node, config || {});
6273 instances.push(node._flatpickr);
6274 }
6275 catch (e) {
6276 console.error(e);
6277 }
6278 }
6279 return instances.length === 1 ? instances[0] : instances;
6280 }
6281 /* istanbul ignore next */
6282 if (typeof HTMLElement !== "undefined") {
6283 // browser env
6284 HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
6285 return _flatpickr(this, config);
6286 };
6287 HTMLElement.prototype.flatpickr = function (config) {
6288 return _flatpickr([this], config);
6289 };
6290 }
6291 /* istanbul ignore next */
6292 var flatpickr = function (selector, config) {
6293 if (typeof selector === "string") {
6294 return _flatpickr(window.document.querySelectorAll(selector), config);
6295 }
6296 else if (selector instanceof Node) {
6297 return _flatpickr([selector], config);
6298 }
6299 else {
6300 return _flatpickr(selector, config);
6301 }
6302 };
6303 /* istanbul ignore next */
6304 flatpickr.defaultConfig = defaults;
6305 flatpickr.l10ns = {
6306 en: __assign({}, english),
6307 "default": __assign({}, english)
6308 };
6309 flatpickr.localize = function (l10n) {
6310 flatpickr.l10ns["default"] = __assign({}, flatpickr.l10ns["default"], l10n);
6311 };
6312 flatpickr.setDefaults = function (config) {
6313 flatpickr.defaultConfig = __assign({}, flatpickr.defaultConfig, config);
6314 };
6315 flatpickr.parseDate = createDateParser({});
6316 flatpickr.formatDate = createDateFormatter({});
6317 flatpickr.compareDates = compareDates;
6318 /* istanbul ignore next */
6319 if (typeof jQuery !== "undefined") {
6320 jQuery.fn.flatpickr = function (config) {
6321 return _flatpickr(this, config);
6322 };
6323 }
6324 Date.prototype.fp_incr = function (days) {
6325 return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === "string" ? parseInt(days, 10) : days));
6326 };
6327 if (typeof window !== "undefined") {
6328 window.flatpickr = flatpickr;
6329 }
6330
6331 return flatpickr;
6332
6333 }));
6334 });
6335
6336 /* eslint no-underscore-dangle: [2, { "allow": ["_input", "_updateClassNames", "_updateInputFields"], "allowAfterThis": true }] */
6337 // `this.options` create-component mix-in creates prototype chain
6338 // so that `options` given in constructor argument wins over the one defined in static `options` property
6339 // 'Flatpickr' wants flat structure of object instead
6340
6341 function flattenOptions(options) {
6342 var o = {}; // eslint-disable-next-line guard-for-in, no-restricted-syntax
6343
6344 for (var key in options) {
6345 o[key] = options[key];
6346 }
6347
6348 return o;
6349 } // Weekdays shorthand for english locale
6350
6351
6352 flatpickr.l10ns.en.weekdays.shorthand.forEach(function (day, index) {
6353 var currentDay = flatpickr.l10ns.en.weekdays.shorthand;
6354
6355 if (currentDay[index] === 'Thu' || currentDay[index] === 'Th') {
6356 currentDay[index] = 'Th';
6357 } else {
6358 currentDay[index] = currentDay[index].charAt(0);
6359 }
6360 });
6361
6362 var toArray$5 = function toArray(arrayLike) {
6363 return Array.prototype.slice.call(arrayLike);
6364 };
6365
6366 var DatePicker =
6367 /*#__PURE__*/
6368 function (_mixin) {
6369 _inherits(DatePicker, _mixin);
6370
6371 /**
6372 * DatePicker.
6373 * @extends CreateComponent
6374 * @extends InitComponentBySearch
6375 * @extends Handles
6376 * @param {HTMLElement} element The element working as an date picker.
6377 */
6378 function DatePicker(element, options) {
6379 var _this;
6380
6381 _classCallCheck(this, DatePicker);
6382
6383 _this = _possibleConstructorReturn(this, _getPrototypeOf(DatePicker).call(this, element, options));
6384
6385 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocus", function () {
6386 if (_this.calendar) {
6387 _this.calendar.open();
6388 }
6389 });
6390
6391 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleBlur", function (event) {
6392 if (_this.calendar) {
6393 var focusTo = event.relatedTarget;
6394
6395 if (!focusTo || !_this.element.contains(focusTo) && (!_this.calendar.calendarContainer || !_this.calendar.calendarContainer.contains(focusTo))) {
6396 _this.calendar.close();
6397 }
6398 }
6399 });
6400
6401 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_initDatePicker", function (type) {
6402 if (type === 'range') {
6403 // Given FlatPickr assumes one `<input>` even in range mode,
6404 // use a hidden `<input>` for such purpose, separate from our from/to `<input>`s
6405 var doc = _this.element.ownerDocument;
6406 var rangeInput = doc.createElement('input');
6407 rangeInput.className = _this.options.classVisuallyHidden;
6408 rangeInput.setAttribute('aria-hidden', 'true');
6409
6410 _this.element.appendChild(rangeInput);
6411
6412 _this._rangeInput = rangeInput; // An attempt to open the date picker dropdown when this component gets focus,
6413 // and close the date picker dropdown when this component loses focus
6414
6415 var w = doc.defaultView;
6416 var hasFocusin = 'onfocusin' in w;
6417 var hasFocusout = 'onfocusout' in w;
6418 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
6419 var focusoutEventName = hasFocusout ? 'focusout' : 'blur';
6420
6421 _this.manage(on(_this.element, focusinEventName, _this._handleFocus, !hasFocusin));
6422
6423 _this.manage(on(_this.element, focusoutEventName, _this._handleBlur, !hasFocusout));
6424
6425 _this.manage(on(_this.element.querySelector(_this.options.selectorDatePickerIcon), focusoutEventName, _this._handleBlur, !hasFocusout));
6426 }
6427
6428 var self = _assertThisInitialized(_assertThisInitialized(_this));
6429
6430 var date = type === 'range' ? _this._rangeInput : _this.element.querySelector(_this.options.selectorDatePickerInput);
6431 var _this$options = _this.options,
6432 _onClose = _this$options.onClose,
6433 _onChange = _this$options.onChange,
6434 _onMonthChange = _this$options.onMonthChange,
6435 _onYearChange = _this$options.onYearChange,
6436 _onOpen = _this$options.onOpen,
6437 _onValueUpdate = _this$options.onValueUpdate;
6438 var calendar = new flatpickr(date, Object.assign(flattenOptions(_this.options), {
6439 allowInput: true,
6440 mode: type,
6441 positionElement: type === 'range' && _this.element.querySelector(_this.options.selectorDatePickerInputFrom),
6442 onClose: function onClose(selectedDates) {
6443 // An attempt to disable Flatpickr's focus tracking system,
6444 // which has adverse effect with our old set up with two `<input>`s or our latest setup with a hidden `<input>`
6445 if (self.shouldForceOpen) {
6446 if (self.calendar.calendarContainer) {
6447 self.calendar.calendarContainer.classList.add('open');
6448 }
6449
6450 self.calendar.isOpen = true;
6451 }
6452
6453 for (var _len = arguments.length, remainder = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6454 remainder[_key - 1] = arguments[_key];
6455 }
6456
6457 if (!_onClose || _onClose.call.apply(_onClose, [this, selectedDates].concat(remainder)) !== false) {
6458 self._updateClassNames(calendar);
6459
6460 self._updateInputFields(selectedDates, type);
6461 }
6462 },
6463 onChange: function onChange() {
6464 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
6465 args[_key2] = arguments[_key2];
6466 }
6467
6468 if (!_onChange || _onChange.call.apply(_onChange, [this].concat(args)) !== false) {
6469 self._updateClassNames(calendar);
6470
6471 if (type === 'range') {
6472 if (calendar.selectedDates.length === 1 && calendar.isOpen) {
6473 self.element.querySelector(self.options.selectorDatePickerInputTo).classList.add(self.options.classFocused);
6474 } else {
6475 self.element.querySelector(self.options.selectorDatePickerInputTo).classList.remove(self.options.classFocused);
6476 }
6477 }
6478 }
6479 },
6480 onMonthChange: function onMonthChange() {
6481 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
6482 args[_key3] = arguments[_key3];
6483 }
6484
6485 if (!_onMonthChange || _onMonthChange.call.apply(_onMonthChange, [this].concat(args)) !== false) {
6486 self._updateClassNames(calendar);
6487 }
6488 },
6489 onYearChange: function onYearChange() {
6490 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
6491 args[_key4] = arguments[_key4];
6492 }
6493
6494 if (!_onYearChange || _onYearChange.call.apply(_onYearChange, [this].concat(args)) !== false) {
6495 self._updateClassNames(calendar);
6496 }
6497 },
6498 onOpen: function onOpen() {
6499 // An attempt to disable Flatpickr's focus tracking system,
6500 // which has adverse effect with our old set up with two `<input>`s or our latest setup with a hidden `<input>`
6501 self.shouldForceOpen = true;
6502 setTimeout(function () {
6503 self.shouldForceOpen = false;
6504 }, 0);
6505
6506 for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
6507 args[_key5] = arguments[_key5];
6508 }
6509
6510 if (!_onOpen || _onOpen.call.apply(_onOpen, [this].concat(args)) !== false) {
6511 self._updateClassNames(calendar);
6512 }
6513 },
6514 onValueUpdate: function onValueUpdate() {
6515 for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
6516 args[_key6] = arguments[_key6];
6517 }
6518
6519 if ((!_onValueUpdate || _onValueUpdate.call.apply(_onValueUpdate, [this].concat(args)) !== false) && type === 'range') {
6520 self._updateInputFields(self.calendar.selectedDates, type);
6521 }
6522 },
6523 nextArrow: _this._rightArrowHTML(),
6524 prevArrow: _this._leftArrowHTML()
6525 }));
6526
6527 if (type === 'range') {
6528 _this._addInputLogic(_this.element.querySelector(_this.options.selectorDatePickerInputFrom), 0);
6529
6530 _this._addInputLogic(_this.element.querySelector(_this.options.selectorDatePickerInputTo), 1);
6531 }
6532
6533 _this.manage(on(_this.element.querySelector(_this.options.selectorDatePickerIcon), 'click', function () {
6534 calendar.open();
6535 }));
6536
6537 _this._updateClassNames(calendar);
6538
6539 if (type !== 'range') {
6540 _this._addInputLogic(date);
6541 }
6542
6543 return calendar;
6544 });
6545
6546 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_addInputLogic", function (input, index) {
6547 if (!isNaN(index) && (index < 0 || index > 1)) {
6548 throw new RangeError("The index of <input> (".concat(index, ") is out of range."));
6549 }
6550
6551 var inputField = input;
6552
6553 _this.manage(on(inputField, 'change', function (evt) {
6554 if (evt.isTrusted || evt.detail && evt.detail.isNotFromFlatpickr) {
6555 var inputDate = _this.calendar.parseDate(inputField.value);
6556
6557 if (inputDate && !isNaN(inputDate.valueOf())) {
6558 if (isNaN(index)) {
6559 _this.calendar.setDate(inputDate);
6560 } else {
6561 var selectedDates = _this.calendar.selectedDates;
6562 selectedDates[index] = inputDate;
6563
6564 _this.calendar.setDate(selectedDates);
6565 }
6566 }
6567 }
6568
6569 _this._updateClassNames(_this.calendar);
6570 })); // An attempt to temporarily set the `<input>` being edited as the one FlatPicker manages,
6571 // as FlatPicker attempts to take over `keydown` event handler on `document` to run on the date picker dropdown.
6572
6573
6574 _this.manage(on(inputField, 'keydown', function (evt) {
6575 var origInput = _this.calendar._input;
6576 _this.calendar._input = evt.target;
6577 setTimeout(function () {
6578 _this.calendar._input = origInput;
6579 });
6580 }));
6581 });
6582
6583 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_updateClassNames", function (_ref) {
6584 var calendarContainer = _ref.calendarContainer,
6585 selectedDates = _ref.selectedDates;
6586
6587 if (calendarContainer) {
6588 calendarContainer.classList.add(_this.options.classCalendarContainer);
6589 calendarContainer.querySelector('.flatpickr-month').classList.add(_this.options.classMonth);
6590 calendarContainer.querySelector('.flatpickr-weekdays').classList.add(_this.options.classWeekdays);
6591 calendarContainer.querySelector('.flatpickr-days').classList.add(_this.options.classDays);
6592 toArray$5(calendarContainer.querySelectorAll('.flatpickr-weekday')).forEach(function (item) {
6593 var currentItem = item;
6594 currentItem.innerHTML = currentItem.innerHTML.replace(/\s+/g, '');
6595 currentItem.classList.add(_this.options.classWeekday);
6596 });
6597 toArray$5(calendarContainer.querySelectorAll('.flatpickr-day')).forEach(function (item) {
6598 item.classList.add(_this.options.classDay);
6599
6600 if (item.classList.contains('today') && selectedDates.length > 0) {
6601 item.classList.add('no-border');
6602 } else if (item.classList.contains('today') && selectedDates.length === 0) {
6603 item.classList.remove('no-border');
6604 }
6605 });
6606 }
6607 });
6608
6609 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_updateInputFields", function (selectedDates, type) {
6610 if (type === 'range') {
6611 if (selectedDates.length === 2) {
6612 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).value = _this._formatDate(selectedDates[0]);
6613 _this.element.querySelector(_this.options.selectorDatePickerInputTo).value = _this._formatDate(selectedDates[1]);
6614 } else if (selectedDates.length === 1) {
6615 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).value = _this._formatDate(selectedDates[0]);
6616 }
6617 } else if (selectedDates.length === 1) {
6618 _this.element.querySelector(_this.options.selectorDatePickerInput).value = _this._formatDate(selectedDates[0]);
6619 }
6620
6621 _this._updateClassNames(_this.calendar);
6622 });
6623
6624 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_formatDate", function (date) {
6625 return _this.calendar.formatDate(date, _this.calendar.config.dateFormat);
6626 });
6627
6628 var _type = _this.element.getAttribute(_this.options.attribType);
6629
6630 _this.calendar = _this._initDatePicker(_type);
6631
6632 if (_this.calendar.calendarContainer) {
6633 _this.manage(on(_this.element, 'keydown', function (e) {
6634 if (e.which === 40) {
6635 _this.calendar.calendarContainer.focus();
6636 }
6637 }));
6638
6639 _this.manage(on(_this.calendar.calendarContainer, 'keydown', function (e) {
6640 if (e.which === 9 && _type === 'range') {
6641 _this._updateClassNames(_this.calendar);
6642
6643 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).focus();
6644 }
6645 }));
6646 }
6647
6648 return _this;
6649 }
6650 /**
6651 * Opens the date picker dropdown when this component gets focus.
6652 * Used only for range mode for now.
6653 * @private
6654 */
6655
6656
6657 _createClass(DatePicker, [{
6658 key: "_rightArrowHTML",
6659 value: function _rightArrowHTML() {
6660 return "\n <svg\n focusable=\"false\"\n preserveAspectRatio=\"xMidYMid meet\"\n style=\"will-change: transform;\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\">\n <path d=\"M11 8l-5 5-.7-.7L9.6 8 5.3 3.7 6 3z\"></path>\n </svg>";
6661 }
6662 }, {
6663 key: "_leftArrowHTML",
6664 value: function _leftArrowHTML() {
6665 return "\n <svg\n focusable=\"false\"\n preserveAspectRatio=\"xMidYMid meet\"\n style=\"will-change: transform;\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 8l5-5 .7.7L6.4 8l4.3 4.3-.7.7z\"></path>\n </svg>";
6666 }
6667 }, {
6668 key: "release",
6669 value: function release() {
6670 if (this._rangeInput && this._rangeInput.parentNode) {
6671 this._rangeInput.parentNode.removeChild(this._rangeInput);
6672 }
6673
6674 if (this.calendar) {
6675 try {
6676 this.calendar.destroy();
6677 } catch (err) {} // eslint-disable-line no-empty
6678
6679
6680 this.calendar = null;
6681 }
6682
6683 return _get(_getPrototypeOf(DatePicker.prototype), "release", this).call(this);
6684 }
6685 /**
6686 * The component options.
6687 * If `options` is specified in the constructor,
6688 * {@linkcode DatePicker.create .create()}, or {@linkcode DatePicker.init .init()},
6689 * properties in this object are overriden for the instance being create and how {@linkcode DatePicker.init .init()} works.
6690 * @property {string} selectorInit The CSS selector to find date picker UIs.
6691 */
6692
6693 }], [{
6694 key: "options",
6695 get: function get$$1() {
6696 var prefix = settings_1.prefix;
6697 return {
6698 selectorInit: '[data-date-picker]',
6699 selectorDatePickerInput: '[data-date-picker-input]',
6700 selectorDatePickerInputFrom: '[data-date-picker-input-from]',
6701 selectorDatePickerInputTo: '[data-date-picker-input-to]',
6702 selectorDatePickerIcon: '[data-date-picker-icon]',
6703 classCalendarContainer: "".concat(prefix, "--date-picker__calendar"),
6704 classMonth: "".concat(prefix, "--date-picker__month"),
6705 classWeekdays: "".concat(prefix, "--date-picker__weekdays"),
6706 classDays: "".concat(prefix, "--date-picker__days"),
6707 classWeekday: "".concat(prefix, "--date-picker__weekday"),
6708 classDay: "".concat(prefix, "--date-picker__day"),
6709 classFocused: "".concat(prefix, "--focused"),
6710 classVisuallyHidden: "".concat(prefix, "--visually-hidden"),
6711 attribType: 'data-date-picker-type',
6712 dateFormat: 'm/d/Y'
6713 };
6714 }
6715 /**
6716 * The map associating DOM element and date picker UI instance.
6717 * @type {WeakMap}
6718 */
6719
6720 }]);
6721
6722 return DatePicker;
6723 }(mixin(createComponent, initComponentBySearch, handles));
6724
6725 _defineProperty(DatePicker, "components",
6726 /* #__PURE_CLASS_PROPERTY__ */
6727 new WeakMap());
6728
6729 var Pagination =
6730 /*#__PURE__*/
6731 function (_mixin) {
6732 _inherits(Pagination, _mixin);
6733
6734 /**
6735 * Pagination component.
6736 * @extends CreateComponent
6737 * @extends InitComponentBySearch
6738 * @param {HTMLElement} element The element working as a pagination component.
6739 * @param {Object} [options] The component options.
6740 * @property {string} [selectorInit] The CSS selector to find pagination components.
6741 * @property {string} [selectorItemsPerPageInput]
6742 * The CSS selector to find the input that determines the number of items per page.
6743 * @property {string} [selectorPageNumberInput] The CSS selector to find the input that changes the page displayed.
6744 * @property {string} [selectorPageBackward] The CSS selector to find the button that goes back a page.
6745 * @property {string} [selectorPageForward] The CSS selector to find the button that goes forward a page.
6746 * @property {string} [eventItemsPerPage]
6747 * The name of the custom event fired when a user changes the number of items per page.
6748 * event.detail.value contains the number of items a user wishes to see.
6749 * @property {string} [eventPageNumber]
6750 * The name of the custom event fired when a user inputs a specific page number.
6751 * event.detail.value contains the value that the user input.
6752 * @property {string} [eventPageChange]
6753 * The name of the custom event fired when a user goes forward or backward a page.
6754 * event.detail.direction contains the direction a user wishes to go.
6755 */
6756 function Pagination(element, options) {
6757 var _this;
6758
6759 _classCallCheck(this, Pagination);
6760
6761 _this = _possibleConstructorReturn(this, _getPrototypeOf(Pagination).call(this, element, options));
6762
6763 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_emitEvent", function (evtName, detail) {
6764 var event = new CustomEvent("".concat(evtName), {
6765 bubbles: true,
6766 cancelable: true,
6767 detail: detail
6768 });
6769
6770 _this.element.dispatchEvent(event);
6771 });
6772
6773 _this.manage(on(_this.element, 'click', function (evt) {
6774 if (evt.target.matches(_this.options.selectorPageBackward)) {
6775 var detail = {
6776 initialEvt: evt,
6777 element: evt.target,
6778 direction: 'backward'
6779 };
6780
6781 _this._emitEvent(_this.options.eventPageChange, detail);
6782 } else if (evt.target.matches(_this.options.selectorPageForward)) {
6783 var _detail = {
6784 initialEvt: evt,
6785 element: evt.target,
6786 direction: 'forward'
6787 };
6788
6789 _this._emitEvent(_this.options.eventPageChange, _detail);
6790 }
6791 }));
6792
6793 _this.manage(on(_this.element, 'input', function (evt) {
6794 if (evt.target.matches(_this.options.selectorItemsPerPageInput)) {
6795 var detail = {
6796 initialEvt: evt,
6797 element: evt.target,
6798 value: evt.target.value
6799 };
6800
6801 _this._emitEvent(_this.options.eventItemsPerPage, detail);
6802 } else if (evt.target.matches(_this.options.selectorPageNumberInput)) {
6803 var _detail2 = {
6804 initialEvt: evt,
6805 element: evt.target,
6806 value: evt.target.value
6807 };
6808
6809 _this._emitEvent(_this.options.eventPageNumber, _detail2);
6810 }
6811 }));
6812
6813 return _this;
6814 }
6815 /**
6816 * Dispatches a custom event
6817 * @param {string} evtName name of the event to be dispatched.
6818 * @param {Object} detail contains the original event and any other necessary details.
6819 */
6820
6821
6822 return Pagination;
6823 }(mixin(createComponent, initComponentBySearch, handles));
6824
6825 _defineProperty(Pagination, "components",
6826 /* #__PURE_CLASS_PROPERTY__ */
6827 new WeakMap());
6828
6829 _defineProperty(Pagination, "options",
6830 /* #__PURE_CLASS_PROPERTY__ */
6831 {
6832 selectorInit: '[data-pagination]',
6833 selectorItemsPerPageInput: '[data-items-per-page]',
6834 selectorPageNumberInput: '[data-page-number-input]',
6835 selectorPageBackward: '[data-page-backward]',
6836 selectorPageForward: '[data-page-forward]',
6837 eventItemsPerPage: 'itemsPerPage',
6838 eventPageNumber: 'pageNumber',
6839 eventPageChange: 'pageChange'
6840 });
6841
6842 /**
6843 * Copyright IBM Corp. 2016, 2018
6844 *
6845 * This source code is licensed under the Apache-2.0 license found in the
6846 * LICENSE file in the root directory of this source tree.
6847 */
6848 function svgToggleClass(svg, name, forceAdd) {
6849 var list = svg.getAttribute('class').trim().split(/\s+/);
6850 var uniqueList = Object.keys(list.reduce(function (o, item) {
6851 return Object.assign(o, _defineProperty({}, item, 1));
6852 }, {}));
6853 var index = uniqueList.indexOf(name);
6854 var found = index >= 0;
6855 var add = forceAdd === undefined ? !found : forceAdd;
6856
6857 if (found === !add) {
6858 if (add) {
6859 uniqueList.push(name);
6860 } else {
6861 uniqueList.splice(index, 1);
6862 }
6863
6864 svg.setAttribute('class', uniqueList.join(' '));
6865 }
6866 }
6867
6868 var toArray$6 = function toArray(arrayLike) {
6869 return Array.prototype.slice.call(arrayLike);
6870 };
6871
6872 var Search =
6873 /*#__PURE__*/
6874 function (_mixin) {
6875 _inherits(Search, _mixin);
6876
6877 /**
6878 * Search with Options.
6879 * @extends CreateComponent
6880 * @extends InitComponentBySearch
6881 * @extends Handles
6882 * @param {HTMLElement} element The element working as the search component.
6883 * @param {Object} [options] The component options
6884 * @property {string} [options.selectorInit]
6885 * The selector to find search UIs with options.
6886 * @property {string} [options.selectorSearchView]
6887 * The selector to find the search view icon containers.
6888 * @property {string} [options.selectorSearchInput]
6889 * The selector to find the search input.
6890 * @property {string} [options.selectorClearIcon]
6891 * The selector for the clear icon that clears the search box.
6892 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
6893 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
6894 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
6895 */
6896 function Search(element, options) {
6897 var _this;
6898
6899 _classCallCheck(this, Search);
6900
6901 _this = _possibleConstructorReturn(this, _getPrototypeOf(Search).call(this, element, options));
6902
6903 var closeIcon = _this.element.querySelector(_this.options.selectorClearIcon);
6904
6905 var input = _this.element.querySelector(_this.options.selectorSearchInput);
6906
6907 if (!input) {
6908 throw new Error('Cannot find the search input.');
6909 }
6910
6911 if (closeIcon) {
6912 _this.manage(on(closeIcon, 'click', function () {
6913 svgToggleClass(closeIcon, _this.options.classClearHidden, true);
6914 input.value = '';
6915 input.focus();
6916 }));
6917 }
6918
6919 _this.manage(on(_this.element, 'click', function (evt) {
6920 var toggleItem = eventMatches(evt, _this.options.selectorIconContainer);
6921 if (toggleItem) _this.toggleLayout(toggleItem);
6922 }));
6923
6924 _this.manage(on(input, 'input', function (evt) {
6925 if (closeIcon) _this.showClear(evt.target.value, closeIcon);
6926 }));
6927
6928 return _this;
6929 }
6930 /**
6931 * Toggles between the grid and list layout.
6932 * @param {HTMLElement} element The element contining the layout toggle.
6933 */
6934
6935
6936 _createClass(Search, [{
6937 key: "toggleLayout",
6938 value: function toggleLayout(element) {
6939 var _this2 = this;
6940
6941 toArray$6(element.querySelectorAll(this.options.selectorSearchView)).forEach(function (item) {
6942 item.classList.toggle(_this2.options.classLayoutHidden);
6943 });
6944 }
6945 /**
6946 * Toggles the clear icon visibility
6947 * @param {HTMLElement} value The element serving as the search input.
6948 * @param {HTMLElement} icon The element serving as close icon.
6949 */
6950
6951 }, {
6952 key: "showClear",
6953 value: function showClear(value, icon) {
6954 svgToggleClass(icon, this.options.classClearHidden, value.length === 0);
6955 }
6956 /**
6957 * The component options.
6958 * If `options` is specified in the constructor,
6959 * {@linkcode Search.create .create()}, or {@linkcode Search.init .init()},
6960 * properties in this object are overriden for the instance being created
6961 * and how {@linkcode Search.init .init()} works.
6962 * @member Search.options
6963 * @type {Object}
6964 * @property {string} [options.selectorInit]
6965 * The selector to find search UIs with options.
6966 * @property {string} [options.selectorSearchView]
6967 * The selector to find the search view icon containers.
6968 * @property {string} [options.selectorSearchInput]
6969 * The selector to find the search input.
6970 * @property {string} [options.selectorClearIcon]
6971 * The selector for the clear icon that clears the search box.
6972 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
6973 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
6974 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
6975 */
6976
6977 }], [{
6978 key: "options",
6979 get: function get() {
6980 var prefix = settings_1.prefix;
6981 return {
6982 selectorInit: '[data-search]',
6983 selectorSearchView: '[data-search-view]',
6984 selectorSearchInput: ".".concat(prefix, "--search-input"),
6985 selectorClearIcon: ".".concat(prefix, "--search-close"),
6986 selectorIconContainer: ".".concat(prefix, "--search-button[data-search-toggle]"),
6987 classClearHidden: "".concat(prefix, "--search-close--hidden"),
6988 classLayoutHidden: "".concat(prefix, "--search-view--hidden")
6989 };
6990 }
6991 /**
6992 * The map associating DOM element and search instance.
6993 * @member Search.components
6994 * @type {WeakMap}
6995 */
6996
6997 }]);
6998
6999 return Search;
7000 }(mixin(createComponent, initComponentBySearch, handles));
7001
7002 _defineProperty(Search, "components",
7003 /* #__PURE_CLASS_PROPERTY__ */
7004 new WeakMap());
7005
7006 var Accordion =
7007 /*#__PURE__*/
7008 function (_mixin) {
7009 _inherits(Accordion, _mixin);
7010
7011 /**
7012 * Accordion.
7013 * @extends CreateComponent
7014 * @extends InitComponentBySearch
7015 * @extends Handles
7016 * @param {HTMLElement} element The element working as an accordion.
7017 */
7018 function Accordion(element, options) {
7019 var _this;
7020
7021 _classCallCheck(this, Accordion);
7022
7023 _this = _possibleConstructorReturn(this, _getPrototypeOf(Accordion).call(this, element, options));
7024
7025 _this.manage(on(_this.element, 'click', function (event) {
7026 var item = eventMatches(event, _this.options.selectorAccordionItem);
7027
7028 if (item && !eventMatches(event, _this.options.selectorAccordionContent)) {
7029 _this._toggle(item);
7030 }
7031 }));
7032 /**
7033 *
7034 * DEPRECATE in v8
7035 *
7036 * Swapping to a button elemenet instead of a div
7037 * automatically maps click events to keypress as well
7038 * This event listener now is only added if user is using
7039 * the older markup
7040 */
7041
7042
7043 if (!_this._checkIfButton()) {
7044 _this.manage(on(_this.element, 'keypress', function (event) {
7045 var item = eventMatches(event, _this.options.selectorAccordionItem);
7046
7047 if (item && !eventMatches(event, _this.options.selectorAccordionContent)) {
7048 _this._handleKeypress(event);
7049 }
7050 }));
7051 }
7052
7053 return _this;
7054 }
7055
7056 _createClass(Accordion, [{
7057 key: "_checkIfButton",
7058 value: function _checkIfButton() {
7059 return this.element.firstElementChild.firstElementChild.nodeName === 'BUTTON';
7060 }
7061 /**
7062 * Handles toggling of active state of accordion via keyboard
7063 * @param {Event} event The event triggering this method.
7064 */
7065
7066 }, {
7067 key: "_handleKeypress",
7068 value: function _handleKeypress(event) {
7069 if (event.which === 13 || event.which === 32) {
7070 this._toggle(event.target);
7071 }
7072 }
7073 }, {
7074 key: "_toggle",
7075 value: function _toggle(element) {
7076 var heading = element.querySelector(this.options.selectorAccordionItemHeading);
7077 var expanded = heading.getAttribute('aria-expanded');
7078
7079 if (expanded !== null) {
7080 heading.setAttribute('aria-expanded', expanded === 'true' ? 'false' : 'true');
7081 }
7082
7083 element.classList.toggle(this.options.classActive);
7084 }
7085 /**
7086 * The component options.
7087 * If `options` is specified in the constructor,
7088 * {@linkcode NumberInput.create .create()}, or {@linkcode NumberInput.init .init()},
7089 * properties in this object are overriden for the instance being create and how {@linkcode NumberInput.init .init()} works.
7090 * @property {string} selectorInit The CSS selector to find accordion UIs.
7091 */
7092
7093 }], [{
7094 key: "options",
7095 get: function get() {
7096 var prefix = settings_1.prefix;
7097 return {
7098 selectorInit: '[data-accordion]',
7099 selectorAccordionItem: ".".concat(prefix, "--accordion__item"),
7100 selectorAccordionItemHeading: ".".concat(prefix, "--accordion__heading"),
7101 selectorAccordionContent: ".".concat(prefix, "--accordion__content"),
7102 classActive: "".concat(prefix, "--accordion__item--active")
7103 };
7104 }
7105 /**
7106 * The map associating DOM element and accordion UI instance.
7107 * @type {WeakMap}
7108 */
7109
7110 }]);
7111
7112 return Accordion;
7113 }(mixin(createComponent, initComponentBySearch, handles));
7114
7115 _defineProperty(Accordion, "components",
7116 /* #__PURE_CLASS_PROPERTY__ */
7117 new WeakMap());
7118
7119 var CopyButton =
7120 /*#__PURE__*/
7121 function (_mixin) {
7122 _inherits(CopyButton, _mixin);
7123
7124 /**
7125 * CopyBtn UI.
7126 * @extends CreateComponent
7127 * @extends InitComponentBySearch
7128 * @extends Handles
7129 * @param {HTMLElement} element The element working as a copy button UI.
7130 */
7131 function CopyButton(element, options) {
7132 var _this;
7133
7134 _classCallCheck(this, CopyButton);
7135
7136 _this = _possibleConstructorReturn(this, _getPrototypeOf(CopyButton).call(this, element, options));
7137
7138 _this.manage(on(_this.element, 'click', function () {
7139 return _this.handleClick();
7140 }));
7141
7142 return _this;
7143 }
7144 /**
7145 * Show the feedback tooltip on click. Hide the feedback tooltip after specified timeout value.
7146 */
7147
7148
7149 _createClass(CopyButton, [{
7150 key: "handleClick",
7151 value: function handleClick() {
7152 var _this2 = this;
7153
7154 var feedback = this.element.querySelector(this.options.feedbackTooltip);
7155
7156 if (feedback) {
7157 feedback.classList.add(this.options.classShowFeedback);
7158 setTimeout(function () {
7159 feedback.classList.remove(_this2.options.classShowFeedback);
7160 }, this.options.timeoutValue);
7161 }
7162 }
7163 /**
7164 * The map associating DOM element and copy button UI instance.
7165 * @member CopyBtn.components
7166 * @type {WeakMap}
7167 */
7168
7169 }], [{
7170 key: "options",
7171
7172 /**
7173 * The component options.
7174 * If `options` is specified in the constructor, {@linkcode CopyBtn.create .create()}, or {@linkcode CopyBtn.init .init()},
7175 * properties in this object are overriden for the instance being create and how {@linkcode CopyBtn.init .init()} works.
7176 * @member CopyBtn.options
7177 * @type {Object}
7178 * @property {string} selectorInit The data attribute to find copy button UIs.
7179 * @property {string} feedbackTooltip The data attribute to find feedback tooltip.
7180 * @property {string} classShowFeedback The CSS selector for showing the feedback tooltip.
7181 * @property {number} timeoutValue The specified timeout value before the feedback tooltip is hidden.
7182 */
7183 get: function get() {
7184 var prefix = settings_1.prefix;
7185 return {
7186 selectorInit: '[data-copy-btn]',
7187 feedbackTooltip: '[data-feedback]',
7188 classShowFeedback: "".concat(prefix, "--btn--copy__feedback--displayed"),
7189 timeoutValue: 2000
7190 };
7191 }
7192 }]);
7193
7194 return CopyButton;
7195 }(mixin(createComponent, initComponentBySearch, handles));
7196
7197 _defineProperty(CopyButton, "components",
7198 /* #__PURE_CLASS_PROPERTY__ */
7199 new WeakMap());
7200
7201 var Notification =
7202 /*#__PURE__*/
7203 function (_mixin) {
7204 _inherits(Notification, _mixin);
7205
7206 /**
7207 * InlineNotification.
7208 * @extends CreateComponent
7209 * @extends InitComponentBySearch
7210 * @extends Handles
7211 * @param {HTMLElement} element The element working as a InlineNotification.
7212 */
7213 function Notification(element, options) {
7214 var _this;
7215
7216 _classCallCheck(this, Notification);
7217
7218 _this = _possibleConstructorReturn(this, _getPrototypeOf(Notification).call(this, element, options));
7219
7220 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
7221 if (state === 'delete-notification') {
7222 _this.element.parentNode.removeChild(_this.element);
7223
7224 _this.release();
7225 }
7226
7227 callback();
7228 });
7229
7230 _this.button = element.querySelector(_this.options.selectorButton);
7231
7232 if (_this.button) {
7233 _this.manage(on(_this.button, 'click', function (evt) {
7234 if (evt.currentTarget === _this.button) {
7235 _this.remove();
7236 }
7237 }));
7238 }
7239
7240 return _this;
7241 }
7242
7243 _createClass(Notification, [{
7244 key: "remove",
7245 value: function remove() {
7246 this.changeState('delete-notification');
7247 }
7248 /**
7249 * The map associating DOM element and accordion UI instance.
7250 * @type {WeakMap}
7251 */
7252
7253 }]);
7254
7255 return Notification;
7256 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
7257
7258 _defineProperty(Notification, "components",
7259 /* #__PURE_CLASS_PROPERTY__ */
7260 new WeakMap());
7261
7262 _defineProperty(Notification, "options",
7263 /* #__PURE_CLASS_PROPERTY__ */
7264 {
7265 selectorInit: '[data-notification]',
7266 selectorButton: '[data-notification-btn]',
7267 eventBeforeDeleteNotification: 'notification-before-delete',
7268 eventAfterDeleteNotification: 'notification-after-delete'
7269 });
7270
7271 var toArray$7 = function toArray(arrayLike) {
7272 return Array.prototype.slice.call(arrayLike);
7273 };
7274
7275 var Toolbar =
7276 /*#__PURE__*/
7277 function (_mixin) {
7278 _inherits(Toolbar, _mixin);
7279
7280 /**
7281 * Toolbar.
7282 * @extends CreateComponent
7283 * @extends InitComponentBySearch
7284 * @extends Handles
7285 * @param {HTMLElement} element The element working as an toolbar.
7286 */
7287 function Toolbar(element, options) {
7288 var _this;
7289
7290 _classCallCheck(this, Toolbar);
7291
7292 _this = _possibleConstructorReturn(this, _getPrototypeOf(Toolbar).call(this, element, options));
7293
7294 if (!_this.element.dataset.tableTarget) {
7295 console.warn('There is no table bound to this toolbar!'); // eslint-disable-line no-console
7296 } else {
7297 var boundTable = _this.element.ownerDocument.querySelector(_this.element.dataset.tableTarget);
7298
7299 var rowHeightBtns = _this.element.querySelector(_this.options.selectorRowHeight);
7300
7301 if (rowHeightBtns) {
7302 _this.manage(on(rowHeightBtns, 'click', function (event) {
7303 _this._handleRowHeightChange(event, boundTable);
7304 })); // toArray(this.element.querySelectorAll(this.options.selectorRowHeight)).forEach((item) => {
7305 // item.addEventListener('click', (event) => { this._handleRowHeightChange(event, boundTable); });
7306 // });
7307
7308 }
7309 }
7310
7311 _this.manage(on(_this.element.ownerDocument, 'keydown', function (evt) {
7312 _this._handleKeyDown(evt);
7313 }));
7314
7315 _this.manage(on(_this.element.ownerDocument, 'click', function (evt) {
7316 _this._handleDocumentClick(evt);
7317 }));
7318
7319 return _this;
7320 }
7321 /**
7322 * Handles toggling of active state of the toolbar search input
7323 * @param {Event} event The event triggering this method.
7324 */
7325
7326
7327 _createClass(Toolbar, [{
7328 key: "_handleDocumentClick",
7329 value: function _handleDocumentClick(event) {
7330 var _this2 = this;
7331
7332 var searchInput = eventMatches(event, this.options.selectorSearch);
7333 var isOfSelfSearchInput = searchInput && this.element.contains(searchInput);
7334
7335 if (isOfSelfSearchInput) {
7336 var shouldBeOpen = isOfSelfSearchInput && !this.element.classList.contains(this.options.classSearchActive);
7337 searchInput.classList.toggle(this.options.classSearchActive, shouldBeOpen);
7338
7339 if (shouldBeOpen) {
7340 searchInput.querySelector('input').focus();
7341 }
7342 }
7343
7344 var targetComponentElement = eventMatches(event, this.options.selectorInit);
7345 toArray$7(this.element.ownerDocument.querySelectorAll(this.options.selectorSearch)).forEach(function (item) {
7346 if (!targetComponentElement || !targetComponentElement.contains(item)) {
7347 item.classList.remove(_this2.options.classSearchActive);
7348 }
7349 });
7350 }
7351 /**
7352 * Handles toggling of active state of the toolbar search input via the keyboard
7353 * @param {Event} event The event triggering this method.
7354 */
7355
7356 }, {
7357 key: "_handleKeyDown",
7358 value: function _handleKeyDown(event) {
7359 var searchInput = eventMatches(event, this.options.selectorSearch);
7360
7361 if (searchInput && event.which === 27) {
7362 searchInput.classList.remove(this.options.classSearchActive);
7363 }
7364 }
7365 /**
7366 * Handles toggling of the row height of the associated table
7367 * @param {Event} event The event triggering this method.
7368 * @param {HTMLElement} boundTable The table associated with the toolbar.
7369 */
7370
7371 }, {
7372 key: "_handleRowHeightChange",
7373 value: function _handleRowHeightChange(event, boundTable) {
7374 var _event$currentTarget$ = event.currentTarget.querySelector('input:checked'),
7375 value = _event$currentTarget$.value;
7376
7377 if (value === 'tall') {
7378 boundTable.classList.add(this.options.classTallRows);
7379 } else {
7380 boundTable.classList.remove(this.options.classTallRows);
7381 }
7382 }
7383 /**
7384 * The map associating DOM element and Toolbar UI instance.
7385 * @type {WeakMap}
7386 */
7387
7388 }], [{
7389 key: "options",
7390
7391 /**
7392 * The component options.
7393 * If `options` is specified in the constructor,
7394 * properties in this object are overriden for the instance being created.
7395 * @property {string} selectorInit The CSS selector to find toolbar instances.
7396 * @property {string} selectorSearch The CSS selector to find search inputs in a toolbar.
7397 * @property {string} selectorRowHeight The CSS selector to find the row height inputs in a toolbar.
7398 * @property {string} classTallRows The CSS class for making table rows into tall rows.
7399 * @property {string} classSearchActive The CSS class the active state of the search input.
7400 */
7401 get: function get() {
7402 var prefix = settings_1.prefix;
7403 return {
7404 selectorInit: '[data-toolbar]',
7405 selectorSearch: '[data-toolbar-search]',
7406 selectorRowHeight: '[data-row-height]',
7407 classTallRows: "".concat(prefix, "--responsive-table--tall"),
7408 classSearchActive: "".concat(prefix, "--toolbar-search--active")
7409 };
7410 }
7411 }]);
7412
7413 return Toolbar;
7414 }(mixin(createComponent, initComponentBySearch, handles));
7415
7416 _defineProperty(Toolbar, "components",
7417 /* #__PURE_CLASS_PROPERTY__ */
7418 new WeakMap());
7419
7420 /**
7421 * lodash (Custom Build) <https://lodash.com/>
7422 * Build: `lodash modularize exports="npm" -o ./`
7423 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
7424 * Released under MIT license <https://lodash.com/license>
7425 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7426 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7427 */
7428
7429 /** Used as the `TypeError` message for "Functions" methods. */
7430 var FUNC_ERROR_TEXT = 'Expected a function';
7431
7432 /** Used as references for various `Number` constants. */
7433 var NAN = 0 / 0;
7434
7435 /** `Object#toString` result references. */
7436 var symbolTag = '[object Symbol]';
7437
7438 /** Used to match leading and trailing whitespace. */
7439 var reTrim = /^\s+|\s+$/g;
7440
7441 /** Used to detect bad signed hexadecimal string values. */
7442 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
7443
7444 /** Used to detect binary string values. */
7445 var reIsBinary = /^0b[01]+$/i;
7446
7447 /** Used to detect octal string values. */
7448 var reIsOctal = /^0o[0-7]+$/i;
7449
7450 /** Built-in method references without a dependency on `root`. */
7451 var freeParseInt = parseInt;
7452
7453 /** Detect free variable `global` from Node.js. */
7454 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
7455
7456 /** Detect free variable `self`. */
7457 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
7458
7459 /** Used as a reference to the global object. */
7460 var root = freeGlobal || freeSelf || Function('return this')();
7461
7462 /** Used for built-in method references. */
7463 var objectProto = Object.prototype;
7464
7465 /**
7466 * Used to resolve the
7467 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
7468 * of values.
7469 */
7470 var objectToString = objectProto.toString;
7471
7472 /* Built-in method references for those with the same name as other `lodash` methods. */
7473 var nativeMax = Math.max,
7474 nativeMin = Math.min;
7475
7476 /**
7477 * Gets the timestamp of the number of milliseconds that have elapsed since
7478 * the Unix epoch (1 January 1970 00:00:00 UTC).
7479 *
7480 * @static
7481 * @memberOf _
7482 * @since 2.4.0
7483 * @category Date
7484 * @returns {number} Returns the timestamp.
7485 * @example
7486 *
7487 * _.defer(function(stamp) {
7488 * console.log(_.now() - stamp);
7489 * }, _.now());
7490 * // => Logs the number of milliseconds it took for the deferred invocation.
7491 */
7492 var now = function() {
7493 return root.Date.now();
7494 };
7495
7496 /**
7497 * Creates a debounced function that delays invoking `func` until after `wait`
7498 * milliseconds have elapsed since the last time the debounced function was
7499 * invoked. The debounced function comes with a `cancel` method to cancel
7500 * delayed `func` invocations and a `flush` method to immediately invoke them.
7501 * Provide `options` to indicate whether `func` should be invoked on the
7502 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
7503 * with the last arguments provided to the debounced function. Subsequent
7504 * calls to the debounced function return the result of the last `func`
7505 * invocation.
7506 *
7507 * **Note:** If `leading` and `trailing` options are `true`, `func` is
7508 * invoked on the trailing edge of the timeout only if the debounced function
7509 * is invoked more than once during the `wait` timeout.
7510 *
7511 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
7512 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
7513 *
7514 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
7515 * for details over the differences between `_.debounce` and `_.throttle`.
7516 *
7517 * @static
7518 * @memberOf _
7519 * @since 0.1.0
7520 * @category Function
7521 * @param {Function} func The function to debounce.
7522 * @param {number} [wait=0] The number of milliseconds to delay.
7523 * @param {Object} [options={}] The options object.
7524 * @param {boolean} [options.leading=false]
7525 * Specify invoking on the leading edge of the timeout.
7526 * @param {number} [options.maxWait]
7527 * The maximum time `func` is allowed to be delayed before it's invoked.
7528 * @param {boolean} [options.trailing=true]
7529 * Specify invoking on the trailing edge of the timeout.
7530 * @returns {Function} Returns the new debounced function.
7531 * @example
7532 *
7533 * // Avoid costly calculations while the window size is in flux.
7534 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
7535 *
7536 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
7537 * jQuery(element).on('click', _.debounce(sendMail, 300, {
7538 * 'leading': true,
7539 * 'trailing': false
7540 * }));
7541 *
7542 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
7543 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
7544 * var source = new EventSource('/stream');
7545 * jQuery(source).on('message', debounced);
7546 *
7547 * // Cancel the trailing debounced invocation.
7548 * jQuery(window).on('popstate', debounced.cancel);
7549 */
7550 function debounce(func, wait, options) {
7551 var lastArgs,
7552 lastThis,
7553 maxWait,
7554 result,
7555 timerId,
7556 lastCallTime,
7557 lastInvokeTime = 0,
7558 leading = false,
7559 maxing = false,
7560 trailing = true;
7561
7562 if (typeof func != 'function') {
7563 throw new TypeError(FUNC_ERROR_TEXT);
7564 }
7565 wait = toNumber(wait) || 0;
7566 if (isObject(options)) {
7567 leading = !!options.leading;
7568 maxing = 'maxWait' in options;
7569 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
7570 trailing = 'trailing' in options ? !!options.trailing : trailing;
7571 }
7572
7573 function invokeFunc(time) {
7574 var args = lastArgs,
7575 thisArg = lastThis;
7576
7577 lastArgs = lastThis = undefined;
7578 lastInvokeTime = time;
7579 result = func.apply(thisArg, args);
7580 return result;
7581 }
7582
7583 function leadingEdge(time) {
7584 // Reset any `maxWait` timer.
7585 lastInvokeTime = time;
7586 // Start the timer for the trailing edge.
7587 timerId = setTimeout(timerExpired, wait);
7588 // Invoke the leading edge.
7589 return leading ? invokeFunc(time) : result;
7590 }
7591
7592 function remainingWait(time) {
7593 var timeSinceLastCall = time - lastCallTime,
7594 timeSinceLastInvoke = time - lastInvokeTime,
7595 result = wait - timeSinceLastCall;
7596
7597 return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
7598 }
7599
7600 function shouldInvoke(time) {
7601 var timeSinceLastCall = time - lastCallTime,
7602 timeSinceLastInvoke = time - lastInvokeTime;
7603
7604 // Either this is the first call, activity has stopped and we're at the
7605 // trailing edge, the system time has gone backwards and we're treating
7606 // it as the trailing edge, or we've hit the `maxWait` limit.
7607 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
7608 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
7609 }
7610
7611 function timerExpired() {
7612 var time = now();
7613 if (shouldInvoke(time)) {
7614 return trailingEdge(time);
7615 }
7616 // Restart the timer.
7617 timerId = setTimeout(timerExpired, remainingWait(time));
7618 }
7619
7620 function trailingEdge(time) {
7621 timerId = undefined;
7622
7623 // Only invoke if we have `lastArgs` which means `func` has been
7624 // debounced at least once.
7625 if (trailing && lastArgs) {
7626 return invokeFunc(time);
7627 }
7628 lastArgs = lastThis = undefined;
7629 return result;
7630 }
7631
7632 function cancel() {
7633 if (timerId !== undefined) {
7634 clearTimeout(timerId);
7635 }
7636 lastInvokeTime = 0;
7637 lastArgs = lastCallTime = lastThis = timerId = undefined;
7638 }
7639
7640 function flush() {
7641 return timerId === undefined ? result : trailingEdge(now());
7642 }
7643
7644 function debounced() {
7645 var time = now(),
7646 isInvoking = shouldInvoke(time);
7647
7648 lastArgs = arguments;
7649 lastThis = this;
7650 lastCallTime = time;
7651
7652 if (isInvoking) {
7653 if (timerId === undefined) {
7654 return leadingEdge(lastCallTime);
7655 }
7656 if (maxing) {
7657 // Handle invocations in a tight loop.
7658 timerId = setTimeout(timerExpired, wait);
7659 return invokeFunc(lastCallTime);
7660 }
7661 }
7662 if (timerId === undefined) {
7663 timerId = setTimeout(timerExpired, wait);
7664 }
7665 return result;
7666 }
7667 debounced.cancel = cancel;
7668 debounced.flush = flush;
7669 return debounced;
7670 }
7671
7672 /**
7673 * Checks if `value` is the
7674 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
7675 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
7676 *
7677 * @static
7678 * @memberOf _
7679 * @since 0.1.0
7680 * @category Lang
7681 * @param {*} value The value to check.
7682 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
7683 * @example
7684 *
7685 * _.isObject({});
7686 * // => true
7687 *
7688 * _.isObject([1, 2, 3]);
7689 * // => true
7690 *
7691 * _.isObject(_.noop);
7692 * // => true
7693 *
7694 * _.isObject(null);
7695 * // => false
7696 */
7697 function isObject(value) {
7698 var type = typeof value;
7699 return !!value && (type == 'object' || type == 'function');
7700 }
7701
7702 /**
7703 * Checks if `value` is object-like. A value is object-like if it's not `null`
7704 * and has a `typeof` result of "object".
7705 *
7706 * @static
7707 * @memberOf _
7708 * @since 4.0.0
7709 * @category Lang
7710 * @param {*} value The value to check.
7711 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
7712 * @example
7713 *
7714 * _.isObjectLike({});
7715 * // => true
7716 *
7717 * _.isObjectLike([1, 2, 3]);
7718 * // => true
7719 *
7720 * _.isObjectLike(_.noop);
7721 * // => false
7722 *
7723 * _.isObjectLike(null);
7724 * // => false
7725 */
7726 function isObjectLike(value) {
7727 return !!value && typeof value == 'object';
7728 }
7729
7730 /**
7731 * Checks if `value` is classified as a `Symbol` primitive or object.
7732 *
7733 * @static
7734 * @memberOf _
7735 * @since 4.0.0
7736 * @category Lang
7737 * @param {*} value The value to check.
7738 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
7739 * @example
7740 *
7741 * _.isSymbol(Symbol.iterator);
7742 * // => true
7743 *
7744 * _.isSymbol('abc');
7745 * // => false
7746 */
7747 function isSymbol(value) {
7748 return typeof value == 'symbol' ||
7749 (isObjectLike(value) && objectToString.call(value) == symbolTag);
7750 }
7751
7752 /**
7753 * Converts `value` to a number.
7754 *
7755 * @static
7756 * @memberOf _
7757 * @since 4.0.0
7758 * @category Lang
7759 * @param {*} value The value to process.
7760 * @returns {number} Returns the number.
7761 * @example
7762 *
7763 * _.toNumber(3.2);
7764 * // => 3.2
7765 *
7766 * _.toNumber(Number.MIN_VALUE);
7767 * // => 5e-324
7768 *
7769 * _.toNumber(Infinity);
7770 * // => Infinity
7771 *
7772 * _.toNumber('3.2');
7773 * // => 3.2
7774 */
7775 function toNumber(value) {
7776 if (typeof value == 'number') {
7777 return value;
7778 }
7779 if (isSymbol(value)) {
7780 return NAN;
7781 }
7782 if (isObject(value)) {
7783 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
7784 value = isObject(other) ? (other + '') : other;
7785 }
7786 if (typeof value != 'string') {
7787 return value === 0 ? value : +value;
7788 }
7789 value = value.replace(reTrim, '');
7790 var isBinary = reIsBinary.test(value);
7791 return (isBinary || reIsOctal.test(value))
7792 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
7793 : (reIsBadHex.test(value) ? NAN : +value);
7794 }
7795
7796 var lodash_debounce = debounce;
7797
7798 function initComponentByEvent (ToMix) {
7799 /**
7800 * Mix-in class to instantiate components upon events.
7801 * @class InitComponentByEvent
7802 */
7803 var InitComponentByEvent =
7804 /*#__PURE__*/
7805 function (_ToMix) {
7806 _inherits(InitComponentByEvent, _ToMix);
7807
7808 function InitComponentByEvent() {
7809 _classCallCheck(this, InitComponentByEvent);
7810
7811 return _possibleConstructorReturn(this, _getPrototypeOf(InitComponentByEvent).apply(this, arguments));
7812 }
7813
7814 _createClass(InitComponentByEvent, null, [{
7815 key: "init",
7816
7817 /**
7818 * `true` suggests that this component is lazily initialized upon an action/event, etc.
7819 * @type {boolean}
7820 */
7821
7822 /**
7823 * Instantiates this component in the given element.
7824 * If the given element indicates that it's an component of this class, instantiates it.
7825 * Otherwise, instantiates this component by clicking on this component in the given node.
7826 * @param {Node} target The DOM node to instantiate this component in. Should be a document or an element.
7827 * @param {Object} [options] The component options.
7828 * @param {string} [options.selectorInit] The CSS selector to find this component.
7829 * @returns {Handle} The handle to remove the event listener to handle clicking.
7830 */
7831 value: function init() {
7832 var _this = this;
7833
7834 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
7835 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7836 var effectiveOptions = Object.assign(Object.create(this.options), options);
7837
7838 if (!target || target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
7839 throw new TypeError('DOM document or DOM element should be given to search for and initialize this widget.');
7840 }
7841
7842 if (target.nodeType === Node.ELEMENT_NODE && target.matches(effectiveOptions.selectorInit)) {
7843 this.create(target, options);
7844 } else {
7845 // To work around non-bubbling `focus` event, use `focusin` event instead of it's available, and "capture mode" otherwise
7846 var hasFocusin = 'onfocusin' in (target.nodeType === Node.ELEMENT_NODE ? target.ownerDocument : target).defaultView;
7847 var handles = effectiveOptions.initEventNames.map(function (name) {
7848 var eventName = name === 'focus' && hasFocusin ? 'focusin' : name;
7849 return on(target, eventName, function (event) {
7850 var element = eventMatches(event, effectiveOptions.selectorInit); // Instantiated components handles events by themselves
7851
7852 if (element && !_this.components.has(element)) {
7853 var component = _this.create(element, options);
7854
7855 if (typeof component.createdByEvent === 'function') {
7856 component.createdByEvent(event);
7857 }
7858 }
7859 }, name === 'focus' && !hasFocusin);
7860 });
7861 return {
7862 release: function release() {
7863 for (var handle = handles.pop(); handle; handle = handles.pop()) {
7864 handle.release();
7865 }
7866 }
7867 };
7868 }
7869
7870 return '';
7871 }
7872 }]);
7873
7874 return InitComponentByEvent;
7875 }(ToMix);
7876
7877 _defineProperty(InitComponentByEvent, "forLazyInit",
7878 /* #__PURE_CLASS_PROPERTY__ */
7879 true);
7880
7881 return InitComponentByEvent;
7882 }
7883
7884 /**
7885 * @param {Element} menuBody The menu body with the menu arrow.
7886 * @param {string} menuDirection Where the floating menu menu should be placed relative to the trigger button.
7887 * @returns {FloatingMenu~offset} The adjustment of the floating menu position, upon the position of the menu arrow.
7888 * @private
7889 */
7890
7891 var getMenuOffset$1 = function getMenuOffset(menuBody, menuDirection) {
7892 var _DIRECTION_LEFT$DIREC, _DIRECTION_LEFT$DIREC2;
7893
7894 var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
7895 var arrowPositionProp = (_DIRECTION_LEFT$DIREC = {}, _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_LEFT, 'right'), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_TOP, 'bottom'), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_RIGHT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_BOTTOM, 'top'), _DIRECTION_LEFT$DIREC)[menuDirection];
7896 var menuPositionAdjustmentProp = (_DIRECTION_LEFT$DIREC2 = {}, _defineProperty(_DIRECTION_LEFT$DIREC2, DIRECTION_LEFT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC2, DIRECTION_TOP, 'top'), _defineProperty(_DIRECTION_LEFT$DIREC2, DIRECTION_RIGHT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC2, DIRECTION_BOTTOM, 'top'), _DIRECTION_LEFT$DIREC2)[menuDirection];
7897 var values = [arrowPositionProp, 'border-bottom-width'].reduce(function (o, name) {
7898 return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
7899 }, {});
7900 var margin = 0;
7901
7902 if (menuDirection !== DIRECTION_BOTTOM) {
7903 var style = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody);
7904 margin = Number((/^([\d-.]+)px$/.exec(style.getPropertyValue('margin-top')) || [])[1]);
7905 }
7906
7907 values[arrowPositionProp] = values[arrowPositionProp] || -6; // IE, etc.
7908
7909 if (Object.keys(values).every(function (name) {
7910 return !isNaN(values[name]);
7911 })) {
7912 var arrowPosition = values[arrowPositionProp],
7913 borderBottomWidth = values['border-bottom-width'];
7914 return _defineProperty({
7915 left: 0,
7916 top: 0
7917 }, menuPositionAdjustmentProp, Math.sqrt(Math.pow(borderBottomWidth, 2) * 2) - arrowPosition + margin * (menuDirection === DIRECTION_TOP ? 2 : 1));
7918 }
7919
7920 return undefined;
7921 };
7922
7923 var Tooltip =
7924 /*#__PURE__*/
7925 function (_mixin) {
7926 _inherits(Tooltip, _mixin);
7927
7928 /**
7929 * Tooltip.
7930 * @extends CreateComponent
7931 * @extends InitComponentBySearch
7932 * @extends Handles
7933 */
7934 function Tooltip(element, options) {
7935 var _this;
7936
7937 _classCallCheck(this, Tooltip);
7938
7939 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tooltip).call(this, element, options));
7940
7941 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_hasContextMenu", false);
7942
7943 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_debouncedHandleClick", lodash_debounce(_this._handleClick, 200));
7944
7945 _this._hookOn(element);
7946
7947 return _this;
7948 }
7949 /**
7950 * A flag to detect if `oncontextmenu` event is fired right before `focus`/`blur` events.
7951 * @type {boolean}
7952 */
7953
7954
7955 _createClass(Tooltip, [{
7956 key: "createdByEvent",
7957
7958 /**
7959 * A method called when this widget is created upon events.
7960 * @param {Event} event The event triggering the creation.
7961 */
7962 value: function createdByEvent(event) {
7963 var relatedTarget = event.relatedTarget,
7964 type = event.type;
7965
7966 this._debouncedHandleClick({
7967 relatedTarget: relatedTarget,
7968 type: type === 'focusin' ? 'focus' : type,
7969 details: getLaunchingDetails(event)
7970 });
7971 }
7972 /**
7973 * Changes the shown/hidden state.
7974 * @param {string} state The new state.
7975 * @param {Object} detail The detail of the event trigging this action.
7976 * @param {Function} callback Callback called when change in state completes.
7977 // */
7978
7979 }, {
7980 key: "changeState",
7981 value: function changeState(state, detail, callback) {
7982 if (!this.tooltip) {
7983 var tooltip = this.element.ownerDocument.querySelector(this.element.getAttribute(this.options.attribTooltipTarget));
7984
7985 if (!tooltip) {
7986 throw new Error('Cannot find the target tooltip.');
7987 } // Lazily create a component instance for tooltip
7988
7989
7990 this.tooltip = FloatingMenu.create(tooltip, {
7991 refNode: this.element,
7992 classShown: this.options.classShown,
7993 offset: this.options.objMenuOffset
7994 });
7995
7996 this._hookOn(tooltip);
7997
7998 this.children.push(this.tooltip);
7999 } // Delegates the action of changing state to the tooltip.
8000 // (And thus the before/after shown/hidden events are fired from the tooltip)
8001
8002
8003 this.tooltip.changeState(state, Object.assign(detail, {
8004 delegatorNode: this.element
8005 }), callback);
8006 }
8007 /**
8008 * Attaches event handlers to show/hide the tooltip.
8009 * @param {Element} element The element to attach the events to.
8010 * @private
8011 */
8012
8013 }, {
8014 key: "_hookOn",
8015 value: function _hookOn(element) {
8016 var _this2 = this;
8017
8018 var hasFocusin = 'onfocusin' in window;
8019 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
8020 [focusinEventName, 'blur', 'touchleave', 'touchcancel'].forEach(function (name) {
8021 _this2.manage(on(element, name, function (event) {
8022 var relatedTarget = event.relatedTarget,
8023 type = event.type;
8024 var hadContextMenu = _this2._hasContextMenu;
8025 _this2._hasContextMenu = type === 'contextmenu';
8026
8027 _this2._debouncedHandleClick({
8028 relatedTarget: relatedTarget,
8029 type: type === 'focusin' ? 'focus' : type,
8030 hadContextMenu: hadContextMenu,
8031 details: getLaunchingDetails(event)
8032 });
8033 }, name === focusinEventName && !hasFocusin));
8034 });
8035 }
8036 /**
8037 * Handles click/focus events.
8038 * @param {Object} params The parameters.
8039 * @param {Element} params.relatedTarget The element that focus went to. (For `blur` event)
8040 * @param {string} params.type The event type triggering this method.
8041 * @param {boolean} params.hadContextMenu
8042 * @param {Object} params.details The event details.
8043 * @private
8044 */
8045
8046 }, {
8047 key: "_handleClick",
8048 value: function _handleClick(_ref2) {
8049 var relatedTarget = _ref2.relatedTarget,
8050 type = _ref2.type,
8051 hadContextMenu = _ref2.hadContextMenu,
8052 details = _ref2.details;
8053 var state = {
8054 focus: 'shown',
8055 blur: 'hidden',
8056 touchleave: 'hidden',
8057 touchcancel: 'hidden'
8058 }[type];
8059 var shouldPreventClose;
8060
8061 if (type === 'blur') {
8062 // Note: SVGElement in IE11 does not have `.contains()`
8063 var wentToSelf = relatedTarget && this.element.contains && this.element.contains(relatedTarget) || this.tooltip && this.tooltip.element.contains(relatedTarget);
8064 shouldPreventClose = hadContextMenu || wentToSelf;
8065 }
8066
8067 if (!shouldPreventClose) {
8068 this.changeState(state, details);
8069 }
8070 }
8071 }], [{
8072 key: "options",
8073 get: function get() {
8074 var prefix = settings_1.prefix;
8075 return {
8076 selectorInit: '[data-tooltip-trigger]',
8077 classShown: "".concat(prefix, "--tooltip--shown"),
8078 attribTooltipTarget: 'data-tooltip-target',
8079 objMenuOffset: getMenuOffset$1,
8080 initEventNames: ['focus']
8081 };
8082 }
8083 }]);
8084
8085 return Tooltip;
8086 }(mixin(createComponent, initComponentByEvent, exports$1, handles));
8087
8088 _defineProperty(Tooltip, "components",
8089 /* #__PURE_CLASS_PROPERTY__ */
8090 new WeakMap());
8091
8092 var toArray$8 = function toArray(arrayLike) {
8093 return Array.prototype.slice.call(arrayLike);
8094 };
8095
8096 var ProgressIndicator =
8097 /*#__PURE__*/
8098 function (_mixin) {
8099 _inherits(ProgressIndicator, _mixin);
8100
8101 /**
8102 * ProgressIndicator.
8103 * @extends CreateComponent
8104 * @extends InitComponentBySearch
8105 * @param {HTMLElement} element The element representing the ProgressIndicator.
8106 * @param {Object} [options] The component options.
8107 * @property {string} [options.selectorStepElement] The CSS selector to find step elements.
8108 * @property {string} [options.selectorCurrent] The CSS selector to find the current step element.
8109 * @property {string} [options.selectorIncomplete] The CSS class to find incomplete step elements.
8110 * @property {string} [options.selectorComplete] The CSS selector to find completed step elements.
8111 * @property {string} [options.classStep] The className for a step element.
8112 * @property {string} [options.classComplete] The className for a completed step element.
8113 * @property {string} [options.classCurrent] The className for the current step element.
8114 * @property {string} [options.classIncomplete] The className for a incomplete step element.
8115 */
8116 function ProgressIndicator(element, options) {
8117 var _this;
8118
8119 _classCallCheck(this, ProgressIndicator);
8120
8121 _this = _possibleConstructorReturn(this, _getPrototypeOf(ProgressIndicator).call(this, element, options));
8122 /**
8123 * The component state.
8124 * @type {Object}
8125 */
8126
8127 _this.state = {
8128 /**
8129 * The current step index.
8130 * @type {number}
8131 */
8132 currentIndex: _this.getCurrent().index,
8133
8134 /**
8135 * Total number of steps.
8136 * @type {number}
8137 */
8138 totalSteps: _this.getSteps().length
8139 };
8140
8141 _this.addOverflowTooltip();
8142
8143 return _this;
8144 }
8145 /**
8146 * Returns all steps with details about element and index.
8147 */
8148
8149
8150 _createClass(ProgressIndicator, [{
8151 key: "getSteps",
8152 value: function getSteps() {
8153 return toArray$8(this.element.querySelectorAll(this.options.selectorStepElement)).map(function (element, index) {
8154 return {
8155 element: element,
8156 index: index
8157 };
8158 });
8159 }
8160 /**
8161 * Returns current step; gives detail about element and index.
8162 */
8163
8164 }, {
8165 key: "getCurrent",
8166 value: function getCurrent() {
8167 var currentEl = this.element.querySelector(this.options.selectorCurrent);
8168 return this.getSteps().filter(function (step) {
8169 return step.element === currentEl;
8170 })[0];
8171 }
8172 /**
8173 * Sets the current step.
8174 * * @param {Number} new step index or use default in `this.state.currentIndex`.
8175 */
8176
8177 }, {
8178 key: "setCurrent",
8179 value: function setCurrent() {
8180 var _this2 = this;
8181
8182 var newCurrentStep = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.currentIndex;
8183 var changed = false;
8184
8185 if (newCurrentStep !== this.state.currentIndex) {
8186 this.state.currentIndex = newCurrentStep;
8187 changed = true;
8188 }
8189
8190 if (changed) {
8191 this.getSteps().forEach(function (step) {
8192 if (step.index < newCurrentStep) {
8193 _this2._updateStep({
8194 element: step.element,
8195 className: _this2.options.classComplete,
8196 html: _this2._getSVGComplete()
8197 });
8198 }
8199
8200 if (step.index === newCurrentStep) {
8201 _this2._updateStep({
8202 element: step.element,
8203 className: _this2.options.classCurrent,
8204 html: _this2._getCurrentSVG()
8205 });
8206 }
8207
8208 if (step.index > newCurrentStep) {
8209 _this2._updateStep({
8210 element: step.element,
8211 className: _this2.options.classIncomplete,
8212 html: _this2._getIncompleteSVG()
8213 });
8214 }
8215 });
8216 }
8217 }
8218 /**
8219 * Update step with correct inline SVG and className
8220 * @param {Object} args
8221 * @param {Object} [args.element] target element
8222 * @param {Object} [args.className] new className
8223 * @param {Object} [args.html] new inline SVG to insert
8224 */
8225
8226 }, {
8227 key: "_updateStep",
8228 value: function _updateStep(args) {
8229 var element = args.element,
8230 className = args.className,
8231 html = args.html;
8232
8233 if (element.firstElementChild) {
8234 element.removeChild(element.firstElementChild);
8235 }
8236
8237 if (!element.classList.contains(className)) {
8238 element.setAttribute('class', this.options.classStep);
8239 element.classList.add(className);
8240 }
8241
8242 element.insertAdjacentHTML('afterbegin', html);
8243 }
8244 /**
8245 * Returns HTML string for an SVG used to represent a compelted step (checkmark)
8246 */
8247
8248 }, {
8249 key: "_getSVGComplete",
8250 value: function _getSVGComplete() {
8251 return "<svg width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"12\"></circle>\n <polygon points=\"10.3 13.6 7.7 11 6.3 12.4 10.3 16.4 17.8 9 16.4 7.6\"></polygon>\n </svg>";
8252 }
8253 /**
8254 * Returns HTML string for an SVG used to represent current step (circles, like a radio button, but not.)
8255 */
8256
8257 }, {
8258 key: "_getCurrentSVG",
8259 value: function _getCurrentSVG() {
8260 return "<svg>\n <circle cx=\"12\" cy=\"12\" r=\"12\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"6\"></circle>\n </svg>";
8261 }
8262 /**
8263 * Returns HTML string for an SVG used to represent incomple step (grey empty circle)
8264 */
8265
8266 }, {
8267 key: "_getIncompleteSVG",
8268 value: function _getIncompleteSVG() {
8269 return "<svg>\n <circle cx=\"12\" cy=\"12\" r=\"12\"></circle>\n </svg>";
8270 }
8271 }, {
8272 key: "addOverflowTooltip",
8273 value: function addOverflowTooltip() {
8274 var _this3 = this;
8275
8276 var stepLabels = toArray$8(this.element.querySelectorAll(this.options.selectorLabel));
8277 var tooltips = toArray$8(this.element.querySelectorAll(this.options.selectorTooltip));
8278 stepLabels.forEach(function (step) {
8279 if (step.scrollWidth > _this3.options.maxWidth) {
8280 step.classList.add(_this3.options.classOverflowLabel);
8281 }
8282 });
8283 tooltips.forEach(function (tooltip) {
8284 var childText = tooltip.querySelector(_this3.options.selectorTooltipText);
8285
8286 if (childText.scrollHeight > _this3.options.tooltipMaxHeight) {
8287 tooltip.classList.add(_this3.options.classTooltipMulti);
8288 }
8289 });
8290 }
8291 }], [{
8292 key: "options",
8293
8294 /**
8295 * The component options.
8296 * If `options` is specified in the constructor,
8297 * {@linkcode ProgressIndicator.create .create()}, or {@linkcode ProgressIndicator.init .init()},
8298 * properties in this object are overriden for the instance being created.
8299 * @member ProgressIndicator.options
8300 * @type {Object}
8301 * @property {string} selectorInit The CSS selector to find content switcher button set.
8302 * @property {string} [selectorStepElement] The CSS selector to find step elements.
8303 * @property {string} [selectorCurrent] The CSS selector to find the current step element.
8304 * @property {string} [selectorIncomplete] The CSS class to find incomplete step elements.
8305 * @property {string} [selectorComplete] The CSS selector to find completed step elements.
8306 * @property {string} [classStep] The className for a step element.
8307 * @property {string} [classComplete] The className for a completed step element.
8308 * @property {string} [classCurrent] The className for the current step element.
8309 * @property {string} [classIncomplete] The className for a incomplete step element.
8310 */
8311 get: function get() {
8312 var prefix = settings_1.prefix;
8313 return {
8314 selectorInit: '[data-progress]',
8315 selectorStepElement: ".".concat(prefix, "--progress-step"),
8316 selectorCurrent: ".".concat(prefix, "--progress-step--current"),
8317 selectorIncomplete: ".".concat(prefix, "--progress-step--incomplete"),
8318 selectorComplete: ".".concat(prefix, "--progress-step--complete"),
8319 selectorLabel: ".".concat(prefix, "--progress-label"),
8320 selectorTooltip: ".".concat(prefix, "--tooltip"),
8321 selectorTooltipText: ".".concat(prefix, "--tooltip__text"),
8322 classStep: "".concat(prefix, "--progress-step"),
8323 classComplete: "".concat(prefix, "--progress-step--complete"),
8324 classCurrent: "".concat(prefix, "--progress-step--current"),
8325 classIncomplete: "".concat(prefix, "--progress-step--incomplete"),
8326 classOverflowLabel: "".concat(prefix, "--progress-label-overflow"),
8327 classTooltipMulti: "".concat(prefix, "--tooltip_multi"),
8328 maxWidth: 87,
8329 tooltipMaxHeight: 21
8330 };
8331 }
8332 }]);
8333
8334 return ProgressIndicator;
8335 }(mixin(createComponent, initComponentBySearch));
8336
8337 _defineProperty(ProgressIndicator, "components",
8338 /* #__PURE_CLASS_PROPERTY__ */
8339 new WeakMap());
8340
8341 var toArray$9 = function toArray(arrayLike) {
8342 return Array.prototype.slice.call(arrayLike);
8343 };
8344
8345 var StructuredList =
8346 /*#__PURE__*/
8347 function (_mixin) {
8348 _inherits(StructuredList, _mixin);
8349
8350 /**
8351 * StructuredList
8352 * @extends CreateComponent
8353 * @extends InitComponentBySearch
8354 * @extends Handles
8355 * @param {HTMLElement} element The root element of tables
8356 * @param {Object} [options] the... options
8357 * @param {string} [options.selectorInit] selector initialization
8358 * @param {string} [options.selectorRow] css selector for selected row
8359 */
8360 function StructuredList(element, options) {
8361 var _this;
8362
8363 _classCallCheck(this, StructuredList);
8364
8365 _this = _possibleConstructorReturn(this, _getPrototypeOf(StructuredList).call(this, element, options));
8366
8367 _this.manage(on(_this.element, 'keydown', function (evt) {
8368 if (evt.which === 37 || evt.which === 38 || evt.which === 39 || evt.which === 40) {
8369 _this._handleKeydownArrow(evt);
8370 }
8371
8372 if (evt.which === 13 || evt.which === 32) {
8373 _this._handleKeydownChecked(evt);
8374 }
8375 }));
8376
8377 _this.manage(on(_this.element, 'click', function (evt) {
8378 _this._handleClick(evt);
8379 }));
8380
8381 return _this;
8382 }
8383
8384 _createClass(StructuredList, [{
8385 key: "_direction",
8386 value: function _direction(evt) {
8387 return {
8388 37: -1,
8389 // backward
8390 38: -1,
8391 // backward
8392 39: 1,
8393 // forward
8394 40: 1 // forward
8395
8396 }[evt.which];
8397 }
8398 }, {
8399 key: "_nextIndex",
8400 value: function _nextIndex(array, arrayItem, direction) {
8401 return array.indexOf(arrayItem) + direction; // returns -1, 0, 1, 2, 3, 4...
8402 }
8403 }, {
8404 key: "_getInput",
8405 value: function _getInput(index) {
8406 var rows = toArray$9(this.element.querySelectorAll(this.options.selectorRow));
8407 return this.element.ownerDocument.querySelector(this.options.selectorListInput(rows[index].getAttribute('for')));
8408 }
8409 }, {
8410 key: "_handleInputChecked",
8411 value: function _handleInputChecked(index) {
8412 var rows = this.element.querySelectorAll(this.options.selectorRow);
8413 var input = this.getInput(index) || rows[index].querySelector('input');
8414 input.checked = true;
8415 }
8416 }, {
8417 key: "_handleClick",
8418 value: function _handleClick(evt) {
8419 var _this2 = this;
8420
8421 var selectedRow = eventMatches(evt, this.options.selectorRow);
8422 toArray$9(this.element.querySelectorAll(this.options.selectorRow)).forEach(function (row) {
8423 return row.classList.remove(_this2.options.classActive);
8424 });
8425
8426 if (selectedRow) {
8427 selectedRow.classList.add(this.options.classActive);
8428 }
8429 } // Handle Enter or Space keydown events for selecting <label> rows
8430
8431 }, {
8432 key: "_handleKeydownChecked",
8433 value: function _handleKeydownChecked(evt) {
8434 var _this3 = this;
8435
8436 evt.preventDefault(); // prevent spacebar from scrolling page
8437
8438 var selectedRow = eventMatches(evt, this.options.selectorRow);
8439 toArray$9(this.element.querySelectorAll(this.options.selectorRow)).forEach(function (row) {
8440 return row.classList.remove(_this3.options.classActive);
8441 });
8442
8443 if (selectedRow) {
8444 selectedRow.classList.add(this.options.classActive);
8445 var input = selectedRow.querySelector(this.options.selectorListInput(selectedRow.getAttribute('for'))) || selectedRow.querySelector('input');
8446 input.checked = true;
8447 }
8448 } // Handle up and down keydown events for selecting <label> rows
8449
8450 }, {
8451 key: "_handleKeydownArrow",
8452 value: function _handleKeydownArrow(evt) {
8453 var _this4 = this;
8454
8455 evt.preventDefault(); // prevent arrow keys from scrolling
8456
8457 var selectedRow = eventMatches(evt, this.options.selectorRow);
8458
8459 var direction = this._direction(evt);
8460
8461 if (direction && selectedRow !== undefined) {
8462 var rows = toArray$9(this.element.querySelectorAll(this.options.selectorRow));
8463 rows.forEach(function (row) {
8464 return row.classList.remove(_this4.options.classActive);
8465 });
8466 var firstIndex = 0;
8467
8468 var nextIndex = this._nextIndex(rows, selectedRow, direction);
8469
8470 var lastIndex = rows.length - 1;
8471
8472 var getSelectedIndex = function getSelectedIndex() {
8473 switch (nextIndex) {
8474 case -1:
8475 return lastIndex;
8476
8477 case rows.length:
8478 return firstIndex;
8479
8480 default:
8481 return nextIndex;
8482 }
8483 };
8484
8485 var selectedIndex = getSelectedIndex();
8486 rows[selectedIndex].classList.add(this.options.classActive);
8487 rows[selectedIndex].focus();
8488
8489 this._handleInputChecked(selectedIndex);
8490 }
8491 }
8492 }], [{
8493 key: "options",
8494 get: function get() {
8495 var prefix = settings_1.prefix;
8496 return {
8497 selectorInit: '[data-structured-list]',
8498 selectorRow: "[data-structured-list] .".concat(prefix, "--structured-list-tbody > label.").concat(prefix, "--structured-list-row"),
8499 selectorListInput: function selectorListInput(id) {
8500 return "#".concat(id, ".").concat(prefix, "--structured-list-input");
8501 },
8502 classActive: "".concat(prefix, "--structured-list-row--selected")
8503 };
8504 }
8505 }]);
8506
8507 return StructuredList;
8508 }(mixin(createComponent, initComponentBySearch, handles));
8509
8510 _defineProperty(StructuredList, "components",
8511 /* #__PURE_CLASS_PROPERTY__ */
8512 new WeakMap());
8513
8514 var Slider =
8515 /*#__PURE__*/
8516 function (_mixin) {
8517 _inherits(Slider, _mixin);
8518
8519 /**
8520 * Slider.
8521 * @extends CreateComponent
8522 * @extends InitComponentBySearch
8523 * @extends Handles
8524 * @param {HTMLElement} element The element working as an slider.
8525 */
8526 function Slider(element, options) {
8527 var _this;
8528
8529 _classCallCheck(this, Slider);
8530
8531 _this = _possibleConstructorReturn(this, _getPrototypeOf(Slider).call(this, element, options));
8532
8533 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, detail, callback) {
8534 callback();
8535 });
8536
8537 _this.sliderActive = false;
8538 _this.dragging = false;
8539 _this.track = _this.element.querySelector(_this.options.selectorTrack);
8540 _this.filledTrack = _this.element.querySelector(_this.options.selectorFilledTrack);
8541 _this.thumb = _this.element.querySelector(_this.options.selectorThumb);
8542 _this.input = _this.element.querySelector(_this.options.selectorInput);
8543
8544 if (_this.element.dataset.sliderInputBox) {
8545 _this.boundInput = _this.element.ownerDocument.querySelector(_this.element.dataset.sliderInputBox);
8546
8547 _this._updateInput();
8548
8549 _this.manage(on(_this.boundInput, 'change', function (evt) {
8550 _this.setValue(evt.target.value);
8551 }));
8552
8553 _this.manage(on(_this.boundInput, 'focus', function (evt) {
8554 evt.target.select();
8555 })); // workaround for safari
8556
8557
8558 _this.manage(on(_this.boundInput, 'mouseup', function (evt) {
8559 evt.preventDefault();
8560 }));
8561 }
8562
8563 _this._updatePosition();
8564
8565 _this.manage(on(_this.thumb, 'mousedown', function () {
8566 _this.sliderActive = true;
8567 }));
8568
8569 _this.manage(on(_this.element.ownerDocument, 'mouseup', function () {
8570 _this.sliderActive = false;
8571 }));
8572
8573 _this.manage(on(_this.element.ownerDocument, 'mousemove', function (evt) {
8574 var disabled = _this.element.classList.contains(_this.options.classDisabled);
8575
8576 if (_this.sliderActive === true && !disabled) {
8577 _this._updatePosition(evt);
8578 }
8579 }));
8580
8581 _this.manage(on(_this.thumb, 'keydown', function (evt) {
8582 var disabled = _this.element.classList.contains(_this.options.classDisabled);
8583
8584 if (!disabled) {
8585 _this._updatePosition(evt);
8586 }
8587 }));
8588
8589 _this.manage(on(_this.track, 'click', function (evt) {
8590 var disabled = _this.element.classList.contains(_this.options.classDisabled);
8591
8592 if (!disabled) {
8593 _this._updatePosition(evt);
8594 }
8595 }));
8596
8597 return _this;
8598 }
8599
8600 _createClass(Slider, [{
8601 key: "_updatePosition",
8602 value: function _updatePosition(evt) {
8603 var _this2 = this;
8604
8605 var _this$_calcValue = this._calcValue(evt),
8606 left = _this$_calcValue.left,
8607 newValue = _this$_calcValue.newValue;
8608
8609 if (this.dragging) {
8610 return;
8611 }
8612
8613 this.dragging = true;
8614 requestAnimationFrame(function () {
8615 _this2.dragging = false;
8616 _this2.thumb.style.left = "".concat(left, "%");
8617 _this2.filledTrack.style.transform = "translate(0%, -50%) scaleX(".concat(left / 100, ")");
8618 _this2.input.value = newValue;
8619
8620 _this2._updateInput();
8621
8622 _this2.changeState('slider-value-change', {
8623 value: newValue
8624 });
8625 });
8626 }
8627 }, {
8628 key: "_calcValue",
8629 value: function _calcValue(evt) {
8630 var _this$getInputProps = this.getInputProps(),
8631 value = _this$getInputProps.value,
8632 min = _this$getInputProps.min,
8633 max = _this$getInputProps.max,
8634 step = _this$getInputProps.step;
8635
8636 var range = max - min;
8637 var valuePercentage = (value - min) / range * 100;
8638 var left;
8639 var newValue;
8640 left = valuePercentage;
8641 newValue = value;
8642
8643 if (evt) {
8644 var type = evt.type;
8645
8646 if (type === 'keydown') {
8647 var direction = {
8648 40: -1,
8649 // decreasing
8650 37: -1,
8651 // decreasing
8652 38: 1,
8653 // increasing
8654 39: 1 // increasing
8655
8656 }[evt.which];
8657
8658 if (direction !== undefined) {
8659 var multiplier = evt.shiftKey === true ? range / step / this.options.stepMultiplier : 1;
8660 var stepMultiplied = step * multiplier;
8661 var stepSize = stepMultiplied / range * 100;
8662 left = valuePercentage + stepSize * direction;
8663 newValue = Number(value) + stepMultiplied * direction;
8664 }
8665 }
8666
8667 if (type === 'mousemove' || type === 'click') {
8668 if (type === 'click') {
8669 this.element.querySelector(this.options.selectorThumb).classList.add(this.options.classThumbClicked);
8670 } else {
8671 this.element.querySelector(this.options.selectorThumb).classList.remove(this.options.classThumbClicked);
8672 }
8673
8674 var track = this.track.getBoundingClientRect();
8675 var unrounded = (evt.clientX - track.left) / track.width;
8676 var rounded = Math.round(range * unrounded / step) * step;
8677 left = rounded / range * 100;
8678 newValue = rounded + min;
8679 }
8680 }
8681
8682 if (newValue <= Number(min)) {
8683 left = 0;
8684 newValue = min;
8685 }
8686
8687 if (newValue >= Number(max)) {
8688 left = 100;
8689 newValue = max;
8690 }
8691
8692 return {
8693 left: left,
8694 newValue: newValue
8695 };
8696 }
8697 }, {
8698 key: "_updateInput",
8699 value: function _updateInput() {
8700 if (this.boundInput) {
8701 this.boundInput.value = this.input.value;
8702 }
8703 }
8704 }, {
8705 key: "getInputProps",
8706 value: function getInputProps() {
8707 var values = {
8708 value: Number(this.input.value),
8709 min: Number(this.input.min),
8710 max: Number(this.input.max),
8711 step: this.input.step ? Number(this.input.step) : 1
8712 };
8713 return values;
8714 }
8715 }, {
8716 key: "setValue",
8717 value: function setValue(value) {
8718 this.input.value = value;
8719
8720 this._updatePosition();
8721 }
8722 }, {
8723 key: "stepUp",
8724 value: function stepUp() {
8725 this.input.stepUp();
8726
8727 this._updatePosition();
8728 }
8729 }, {
8730 key: "stepDown",
8731 value: function stepDown() {
8732 this.input.stepDown();
8733
8734 this._updatePosition();
8735 }
8736 /**
8737 * The map associating DOM element and Slider UI instance.
8738 * @type {WeakMap}
8739 */
8740
8741 }], [{
8742 key: "options",
8743
8744 /**
8745 * The component options.
8746 * If `options` is specified in the constructor,
8747 * properties in this object are overriden for the instance being created.
8748 * @property {string} selectorInit The CSS selector to find slider instances.
8749 */
8750 get: function get() {
8751 var prefix = settings_1.prefix;
8752 return {
8753 selectorInit: '[data-slider]',
8754 selectorTrack: ".".concat(prefix, "--slider__track"),
8755 selectorFilledTrack: ".".concat(prefix, "--slider__filled-track"),
8756 selectorThumb: ".".concat(prefix, "--slider__thumb"),
8757 selectorInput: ".".concat(prefix, "--slider__input"),
8758 classDisabled: "".concat(prefix, "--slider--disabled"),
8759 classThumbClicked: "".concat(prefix, "--slider__thumb--clicked"),
8760 eventBeforeSliderValueChange: 'slider-before-value-change',
8761 eventAfterSliderValueChange: 'slider-after-value-change',
8762 stepMultiplier: 4
8763 };
8764 }
8765 }]);
8766
8767 return Slider;
8768 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
8769
8770 _defineProperty(Slider, "components",
8771 /* #__PURE_CLASS_PROPERTY__ */
8772 new WeakMap());
8773
8774 var Tile =
8775 /*#__PURE__*/
8776 function (_mixin) {
8777 _inherits(Tile, _mixin);
8778
8779 /**
8780 * Tile.
8781 * @extends CreateComponent
8782 * @extends InitComponentBySearch
8783 * @param {HTMLElement} element The element working as an Tile.
8784 */
8785 function Tile(element, options) {
8786 var _this;
8787
8788 _classCallCheck(this, Tile);
8789
8790 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tile).call(this, element, options));
8791
8792 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getClass", function (type) {
8793 var typeObj = {
8794 expandable: _this.options.classExpandedTile,
8795 clickable: _this.options.classClickableTile,
8796 selectable: _this.options.classSelectableTile
8797 };
8798 return typeObj[type];
8799 });
8800
8801 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_hookActions", function (tileClass) {
8802 var isExpandable = _this.tileType === 'expandable';
8803
8804 if (isExpandable) {
8805 var aboveTheFold = _this.element.querySelector(_this.options.selectorAboveTheFold);
8806
8807 var getStyle = _this.element.ownerDocument.defaultView.getComputedStyle(_this.element, null);
8808
8809 var tilePaddingTop = parseInt(getStyle.getPropertyValue('padding-top'), 10);
8810 var tilePaddingBottom = parseInt(getStyle.getPropertyValue('padding-bottom'), 10);
8811 var tilePadding = tilePaddingTop + tilePaddingBottom;
8812
8813 if (aboveTheFold) {
8814 _this.tileHeight = _this.element.getBoundingClientRect().height;
8815 _this.atfHeight = aboveTheFold.getBoundingClientRect().height + tilePadding;
8816 _this.element.style.maxHeight = "".concat(_this.atfHeight, "px");
8817 }
8818
8819 if (_this.element.classList.contains(_this.options.classExpandedTile)) {
8820 _this._setTileHeight();
8821 }
8822 }
8823
8824 _this.element.addEventListener('click', function (evt) {
8825 var input = eventMatches(evt, _this.options.selectorTileInput);
8826
8827 if (!input) {
8828 _this.element.classList.toggle(tileClass);
8829 }
8830
8831 if (isExpandable) {
8832 _this._setTileHeight();
8833 }
8834 });
8835
8836 _this.element.addEventListener('keydown', function (evt) {
8837 var input = _this.element.querySelector(_this.options.selectorTileInput);
8838
8839 if (input) {
8840 if (evt.which === 13 || evt.which === 32) {
8841 if (!isExpandable) {
8842 _this.element.classList.toggle(tileClass);
8843
8844 input.checked = !input.checked;
8845 }
8846 }
8847 }
8848 });
8849 });
8850
8851 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setTileHeight", function () {
8852 var isExpanded = _this.element.classList.contains(_this.options.classExpandedTile);
8853
8854 _this.element.style.maxHeight = isExpanded ? "".concat(_this.tileHeight, "px") : "".concat(_this.atfHeight, "px");
8855 });
8856
8857 _this.tileType = _this.element.dataset.tile;
8858 _this.tileHeight = 0; // Tracks expandable tile height
8859
8860 _this.atfHeight = 0; // Tracks above the fold height
8861
8862 _this._hookActions(_this._getClass(_this.tileType));
8863
8864 return _this;
8865 }
8866
8867 _createClass(Tile, [{
8868 key: "release",
8869 value: function release() {
8870 _get(_getPrototypeOf(Tile.prototype), "release", this).call(this);
8871 }
8872 /**
8873 * The map associating DOM element and Tile UI instance.
8874 * @type {WeakMap}
8875 */
8876
8877 }], [{
8878 key: "options",
8879
8880 /**
8881 * The component options.
8882 * If `options` is specified in the constructor,
8883 * properties in this object are overriden for the instance being created.
8884 * @property {string} selectorInit The CSS selector to find Tile instances.
8885 */
8886 get: function get$$1() {
8887 var prefix = settings_1.prefix;
8888 return {
8889 selectorInit: '[data-tile]',
8890 selectorAboveTheFold: '[data-tile-atf]',
8891 selectorTileInput: '[data-tile-input]',
8892 classExpandedTile: "".concat(prefix, "--tile--is-expanded"),
8893 classClickableTile: "".concat(prefix, "--tile--is-clicked"),
8894 classSelectableTile: "".concat(prefix, "--tile--is-selected")
8895 };
8896 }
8897 }]);
8898
8899 return Tile;
8900 }(mixin(createComponent, initComponentBySearch));
8901
8902 _defineProperty(Tile, "components",
8903 /* #__PURE_CLASS_PROPERTY__ */
8904 new WeakMap());
8905
8906 var CodeSnippet =
8907 /*#__PURE__*/
8908 function (_mixin) {
8909 _inherits(CodeSnippet, _mixin);
8910
8911 /**
8912 * CodeSnippet UI.
8913 * @extends CreateComponent
8914 * @extends InitComponentBySearch
8915 * @extends Handles
8916 * @param {HTMLElement} element The element working as a CodeSnippet UI.
8917 */
8918 function CodeSnippet(element, options) {
8919 var _this;
8920
8921 _classCallCheck(this, CodeSnippet);
8922
8923 _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeSnippet).call(this, element, options));
8924
8925 _this._initCodeSnippet();
8926
8927 _this.element.querySelector(_this.options.classExpandBtn).addEventListener('click', function (evt) {
8928 return _this._handleClick(evt);
8929 });
8930
8931 return _this;
8932 }
8933
8934 _createClass(CodeSnippet, [{
8935 key: "_handleClick",
8936 value: function _handleClick() {
8937 var expandBtn = this.element.querySelector(this.options.classExpandText);
8938 this.element.classList.toggle(this.options.classExpanded);
8939
8940 if (this.element.classList.contains(this.options.classExpanded)) {
8941 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowLessText);
8942 } else {
8943 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowMoreText);
8944 }
8945 }
8946 }, {
8947 key: "_initCodeSnippet",
8948 value: function _initCodeSnippet() {
8949 var expandBtn = this.element.querySelector(this.options.classExpandText);
8950
8951 if (!expandBtn) {
8952 throw new TypeError('Cannot find the expand button.');
8953 }
8954
8955 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowMoreText);
8956
8957 if (this.element.offsetHeight < this.options.minHeight) {
8958 this.element.classList.add(this.options.classHideExpand);
8959 }
8960 }
8961 /**
8962 * The map associating DOM element and code snippet UI instance.
8963 * @member CodeSnippet.components
8964 * @type {WeakMap}
8965 */
8966
8967 }], [{
8968 key: "options",
8969
8970 /**
8971 * The component options.
8972 * If `options` is specified in the constructor, {@linkcode CodeSnippet.create .create()},
8973 * or {@linkcode CodeSnippet.init .init()},
8974 * properties in this object are overriden for the instance being create and how {@linkcode CodeSnippet.init .init()} works.
8975 * @member CodeSnippet.options
8976 * @type {Object}
8977 * @property {string} selectorInit The data attribute to find code snippet UIs.
8978 */
8979 get: function get() {
8980 var prefix = settings_1.prefix;
8981 return {
8982 selectorInit: '[data-code-snippet]',
8983 attribShowMoreText: 'data-show-more-text',
8984 attribShowLessText: 'data-show-less-text',
8985 minHeight: 288,
8986 classExpanded: "".concat(prefix, "--snippet--expand"),
8987 classExpandBtn: ".".concat(prefix, "--snippet-btn--expand"),
8988 classExpandText: ".".concat(prefix, "--snippet-btn--text"),
8989 classHideExpand: "".concat(prefix, "--snippet-btn--expand--hide")
8990 };
8991 }
8992 }]);
8993
8994 return CodeSnippet;
8995 }(mixin(createComponent, initComponentBySearch, handles));
8996
8997 _defineProperty(CodeSnippet, "components",
8998 /* #__PURE_CLASS_PROPERTY__ */
8999 new WeakMap());
9000
9001 var TextInput =
9002 /*#__PURE__*/
9003 function (_mixin) {
9004 _inherits(TextInput, _mixin);
9005
9006 /**
9007 * Text Input.
9008 * @extends CreateComponent
9009 * @extends InitComponentBySearch
9010 * @extends Handles
9011 * @param {HTMLElement} element - The element functioning as a text field.
9012 */
9013 function TextInput(_element, options) {
9014 var _this;
9015
9016 _classCallCheck(this, TextInput);
9017
9018 _this = _possibleConstructorReturn(this, _getPrototypeOf(TextInput).call(this, _element, options));
9019
9020 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setIconVisibility", function (_ref) {
9021 var iconVisibilityOn = _ref.iconVisibilityOn,
9022 iconVisibilityOff = _ref.iconVisibilityOff,
9023 passwordIsVisible = _ref.passwordIsVisible,
9024 selectorPasswordVisibilityButton = _ref.selectorPasswordVisibilityButton;
9025
9026 if (passwordIsVisible) {
9027 iconVisibilityOn.setAttribute('hidden', true);
9028 iconVisibilityOff.removeAttribute('hidden');
9029 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Hide password');
9030 return;
9031 }
9032
9033 iconVisibilityOn.removeAttribute('hidden');
9034 iconVisibilityOff.setAttribute('hidden', true);
9035 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Show password');
9036 });
9037
9038 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggle", function (_ref2) {
9039 var element = _ref2.element,
9040 button = _ref2.button;
9041 // toggle action must come before querying the classList
9042 element.classList.toggle(_this.options.passwordIsVisible);
9043 var passwordIsVisible = element.classList.contains(_this.options.passwordIsVisible);
9044 var iconVisibilityOn = button.querySelector(_this.options.svgIconVisibilityOn);
9045 var iconVisibilityOff = button.querySelector(_this.options.svgIconVisibilityOff);
9046 var input = element.querySelector(_this.options.selectorPasswordField);
9047 var selectorPasswordVisibilityButton = element.querySelector(_this.options.selectorPasswordVisibilityButton);
9048
9049 _this._setIconVisibility({
9050 iconVisibilityOn: iconVisibilityOn,
9051 iconVisibilityOff: iconVisibilityOff,
9052 passwordIsVisible: passwordIsVisible,
9053 selectorPasswordVisibilityButton: selectorPasswordVisibilityButton
9054 });
9055
9056 input.type = passwordIsVisible ? 'text' : 'password';
9057 });
9058
9059 _this.manage(on(_this.element, 'click', function (event) {
9060 var toggleVisibilityButton = eventMatches(event, _this.options.selectorPasswordVisibilityButton);
9061
9062 if (toggleVisibilityButton) {
9063 _this._toggle({
9064 element: _element,
9065 button: toggleVisibilityButton
9066 });
9067 }
9068 }));
9069
9070 return _this;
9071 }
9072 /**
9073 *
9074 * @param {Object} obj - Object containing selectors and visibility status
9075 * @param {HTMLElement} obj.iconVisibilityOn - The element functioning as
9076 * the SVG icon for visibility on
9077 * @param {HTMLElement} obj.iconVisibilityOff - The element functioning as
9078 * the SVG icon for visibility off
9079 * @param {boolean} obj.passwordIsVisible - The visibility of the password in the
9080 * input field
9081 */
9082
9083
9084 _createClass(TextInput, null, [{
9085 key: "options",
9086
9087 /**
9088 * The component options.
9089 *
9090 * If `options` is specified in the constructor,
9091 * {@linkcode TextInput.create .create()},
9092 * or {@linkcode TextInput.init .init()},
9093 * properties in this object are overriden for the instance being
9094 * created and how {@linkcode TextInput.init .init()} works.
9095 * @property {string} selectorInit The CSS selector to find text input UIs.
9096 */
9097 get: function get() {
9098 var prefix = settings_1.prefix;
9099 return {
9100 selectorInit: '[data-text-input]',
9101 selectorPasswordField: ".".concat(prefix, "--text-input[data-toggle-password-visibility]"),
9102 selectorPasswordVisibilityButton: ".".concat(prefix, "--text-input--password__visibility"),
9103 passwordIsVisible: "".concat(prefix, "--text-input--password-visible"),
9104 svgIconVisibilityOn: "svg.".concat(prefix, "--icon--visibility-on"),
9105 svgIconVisibilityOff: "svg.".concat(prefix, "--icon--visibility-off")
9106 };
9107 }
9108 /**
9109 * The map associating DOM element and text input UI instance.
9110 * @type {WeakMap}
9111 */
9112
9113 }]);
9114
9115 return TextInput;
9116 }(mixin(createComponent, initComponentBySearch, handles));
9117
9118 _defineProperty(TextInput, "components",
9119 /* #__PURE_CLASS_PROPERTY__ */
9120 new WeakMap());
9121
9122 var prefix = settings_1.prefix;
9123
9124 var SideNav =
9125 /*#__PURE__*/
9126 function (_mixin) {
9127 _inherits(SideNav, _mixin);
9128
9129 /**
9130 * The map associating DOM element and copy button UI instance.
9131 * @member SideNav.components
9132 * @type {WeakMap}
9133 */
9134 function SideNav(element, options) {
9135 var _this;
9136
9137 _classCallCheck(this, SideNav);
9138
9139 _this = _possibleConstructorReturn(this, _getPrototypeOf(SideNav).call(this, element, options));
9140
9141 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleClick", function (evt) {
9142 var matchesToggle = eventMatches(evt, _this.options.selectorSideNavToggle);
9143 var matchesNavSubmenu = eventMatches(evt, _this.options.selectorSideNavSubmenu);
9144 var matchesSideNavLink = eventMatches(evt, _this.options.selectorSideNavLink);
9145
9146 if (!matchesToggle && !matchesNavSubmenu && !matchesSideNavLink) {
9147 return;
9148 }
9149
9150 if (matchesToggle) {
9151 _this.changeState(!_this.isNavExpanded() ? _this.constructor.state.EXPANDED : _this.constructor.state.COLLAPSED);
9152
9153 return;
9154 }
9155
9156 if (matchesNavSubmenu) {
9157 var isSubmenuExpanded = matchesNavSubmenu.getAttribute('aria-expanded') === 'true';
9158 matchesNavSubmenu.setAttribute('aria-expanded', "".concat(!isSubmenuExpanded));
9159 return;
9160 }
9161
9162 if (matchesSideNavLink) {
9163 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorSideNavLinkCurrent)).forEach(function (el) {
9164 el.classList.remove(_this.options.classSideNavItemActive, _this.options.classSideNavLinkCurrent);
9165 el.removeAttribute('aria-current');
9166 });
9167
9168 matchesSideNavLink.classList.add(_this.options.classSideNavLinkCurrent);
9169 var closestSideNavItem = matchesSideNavLink.closest(_this.options.selectorSideNavItem);
9170
9171 if (closestSideNavItem) {
9172 closestSideNavItem.classList.add(_this.options.classSideNavItemActive);
9173 }
9174 }
9175 });
9176
9177 _this.manage(on(element, 'click', _this._handleClick));
9178
9179 return _this;
9180 }
9181 /**
9182 * Enum for toggling side nav visibility
9183 * @readonly
9184 * @member SideNav.state
9185 * @type {Object}
9186 * @property {string} EXPANDED Opening/visible
9187 * @property {string} COLLAPSED Closing/hidden
9188 */
9189
9190
9191 _createClass(SideNav, [{
9192 key: "isNavExpanded",
9193
9194 /**
9195 * @returns {boolean} `true` if the nav is expanded.
9196 */
9197 value: function isNavExpanded() {
9198 return this.element.classList.contains(this.options.classSideNavExpanded);
9199 }
9200 /**
9201 * Changes the expanded/collapsed state.
9202 */
9203
9204 }, {
9205 key: "changeState",
9206 value: function changeState(state) {
9207 this.element.classList.toggle(this.options.classSideNavExpanded, state === this.constructor.state.EXPANDED);
9208 }
9209 }]);
9210
9211 return SideNav;
9212 }(mixin(createComponent, initComponentBySearch, handles));
9213
9214 _defineProperty(SideNav, "components",
9215 /* #__PURE_CLASS_PROPERTY__ */
9216 new WeakMap());
9217
9218 _defineProperty(SideNav, "state",
9219 /* #__PURE_CLASS_PROPERTY__ */
9220 {
9221 EXPANDED: 'expanded',
9222 COLLAPSED: 'collapsed'
9223 });
9224
9225 _defineProperty(SideNav, "options",
9226 /* #__PURE_CLASS_PROPERTY__ */
9227 {
9228 selectorInit: '[data-side-nav]',
9229 selectorSideNavToggle: ".".concat(prefix, "--side-nav__toggle"),
9230 selectorSideNavSubmenu: ".".concat(prefix, "--side-nav__submenu"),
9231 selectorSideNavItem: ".".concat(prefix, "--side-nav__item"),
9232 selectorSideNavLink: ".".concat(prefix, "--side-nav__link"),
9233 selectorSideNavLinkCurrent: "[aria-current=\"page\"],.".concat(prefix, "--side-nav__link--current,.").concat(prefix, "--side-nav__item--active"),
9234 classSideNavExpanded: "".concat(prefix, "--side-nav--expanded"),
9235 classSideNavItemActive: "".concat(prefix, "--side-nav__item--active"),
9236 classSideNavLinkCurrent: "".concat(prefix, "--side-nav__link--current")
9237 });
9238
9239 var forEach =
9240 /* #__PURE__ */
9241 function () {
9242 return Array.prototype.forEach;
9243 }();
9244
9245 var toArray$a = function toArray(arrayLike) {
9246 return Array.prototype.slice.call(arrayLike);
9247 };
9248
9249 var HeaderSubmenu =
9250 /*#__PURE__*/
9251 function (_mixin) {
9252 _inherits(HeaderSubmenu, _mixin);
9253
9254 function HeaderSubmenu(element, options) {
9255 var _this;
9256
9257 _classCallCheck(this, HeaderSubmenu);
9258
9259 _this = _possibleConstructorReturn(this, _getPrototypeOf(HeaderSubmenu).call(this, element, options));
9260
9261 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getAction", function (event) {
9262 var isFlyoutMenu = eventMatches(event, _this.options.selectorFlyoutMenu);
9263
9264 if (isFlyoutMenu) {
9265 return _this.constructor.actions.DELEGATE_TO_FLYOUT_MENU;
9266 }
9267
9268 switch (event.type) {
9269 case 'keydown':
9270 return {
9271 32: _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS,
9272 // space bar
9273 13: _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS,
9274 // enter
9275 27: _this.constructor.actions.CLOSE_SUBMENU // esc
9276 // possible arrow keys
9277
9278 }[event.which];
9279
9280 case 'click':
9281 return eventMatches(event, _this.options.selectorItem) ? _this.constructor.actions.CLOSE_SUBMENU : null;
9282
9283 case 'blur':
9284 case 'focusout':
9285 {
9286 var isOfSelf = _this.element.contains(event.relatedTarget);
9287
9288 return isOfSelf ? null : _this.constructor.actions.CLOSE_SUBMENU;
9289 }
9290
9291 case 'mouseenter':
9292 return _this.constructor.actions.OPEN_SUBMENU;
9293
9294 case 'mouseleave':
9295 return _this.constructor.actions.CLOSE_SUBMENU;
9296
9297 default:
9298 return null;
9299 }
9300 });
9301
9302 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getNewState", function (action) {
9303 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
9304
9305 var isExpanded = trigger.getAttribute(_this.options.attribExpanded) === 'true';
9306
9307 switch (action) {
9308 case _this.constructor.actions.CLOSE_SUBMENU:
9309 return false;
9310
9311 case _this.constructor.actions.OPEN_SUBMENU:
9312 return true;
9313
9314 case _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS:
9315 return !isExpanded;
9316
9317 default:
9318 return isExpanded;
9319 }
9320 });
9321
9322 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setState", function (_ref) {
9323 var shouldBeExpanded = _ref.shouldBeExpanded,
9324 shouldFocusOnOpen = _ref.shouldFocusOnOpen;
9325
9326 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
9327
9328 trigger.setAttribute(_this.options.attribExpanded, shouldBeExpanded);
9329 forEach.call(_this.element.querySelectorAll(_this.options.selectorItem), function (item) {
9330 item.tabIndex = shouldBeExpanded ? 0 : -1;
9331 }); // focus first submenu item
9332
9333 if (shouldBeExpanded && shouldFocusOnOpen) {
9334 _this.element.querySelector(_this.options.selectorItem).focus();
9335 }
9336 });
9337
9338 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
9339 var focused = _this.element.ownerDocument.activeElement;
9340 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(_this.options.selectorItem) ? focused : null;
9341 });
9342
9343 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
9344 var items = toArray$a(_this.element.querySelectorAll(_this.options.selectorItem));
9345
9346 var start = _this.getCurrentNavigation() || _this.element.querySelector(_this.options.selectorItemSelected);
9347
9348 var getNextItem = function getNextItem(old) {
9349 var handleUnderflow = function handleUnderflow(index, length) {
9350 return index + (index >= 0 ? 0 : length);
9351 };
9352
9353 var handleOverflow = function handleOverflow(index, length) {
9354 return index - (index < length ? 0 : length);
9355 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
9356
9357
9358 var index = Math.max(items.indexOf(old) + direction, -1);
9359 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
9360 };
9361
9362 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
9363 if (!current.matches(_this.options.selectorItemHidden) && !current.parentNode.matches(_this.options.selectorItemHidden) && !current.matches(_this.options.selectorItemSelected)) {
9364 current.focus();
9365 break;
9366 }
9367 }
9368 });
9369
9370 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleEvent", function (event) {
9371 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
9372
9373 if (!trigger) {
9374 return;
9375 }
9376
9377 var action = _this._getAction(event);
9378
9379 if (action) {
9380 var shouldBeExpanded = _this._getNewState(action);
9381
9382 _this._setState({
9383 shouldBeExpanded: shouldBeExpanded
9384 });
9385 }
9386 });
9387
9388 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
9389 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
9390
9391 if (!trigger) {
9392 return;
9393 }
9394
9395 var action = _this._getAction(event);
9396
9397 if (event.which === 32) {
9398 event.preventDefault();
9399 }
9400
9401 switch (action) {
9402 case _this.constructor.actions.DELEGATE_TO_FLYOUT_MENU:
9403 // currently we do not have a scenario that handles flyout menu
9404 // handleFlyoutMenu
9405 break;
9406 // currently we do not have a scenario that opens a submenu on keydown
9407 // case this.constructor.actions.OPEN_SUBMENU:
9408
9409 case _this.constructor.actions.CLOSE_SUBMENU:
9410 {
9411 var shouldBeExpanded = _this._getNewState(action);
9412
9413 _this._setState({
9414 shouldBeExpanded: shouldBeExpanded
9415 });
9416
9417 break;
9418 }
9419
9420 case _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS:
9421 {
9422 var _shouldBeExpanded = _this._getNewState(action);
9423
9424 _this._setState({
9425 shouldBeExpanded: _shouldBeExpanded,
9426 shouldFocusOnOpen: true
9427 });
9428
9429 break;
9430 }
9431
9432 default:
9433 {
9434 var expanded = trigger.getAttribute(_this.options.attribExpanded) === 'true';
9435
9436 if (expanded) {
9437 var direction = {
9438 38: _this.constructor.NAVIGATE.BACKWARD,
9439 40: _this.constructor.NAVIGATE.FORWARD
9440 }[event.which];
9441
9442 switch (event.which) {
9443 case 35:
9444 {
9445 // end key
9446 event.preventDefault(); // prevents key from scrolling page
9447
9448 var menuItems = _this.element.querySelectorAll(_this.options.selectorItem);
9449
9450 var lastMenuItem = menuItems[menuItems.length - 1];
9451
9452 if (lastMenuItem) {
9453 lastMenuItem.focus();
9454 }
9455
9456 break;
9457 }
9458
9459 case 36:
9460 {
9461 // home key
9462 event.preventDefault(); // prevents key from scrolling page
9463
9464 var _this$element$querySe = _this.element.querySelectorAll(_this.options.selectorItem),
9465 _this$element$querySe2 = _slicedToArray(_this$element$querySe, 1),
9466 firstMenuItem = _this$element$querySe2[0];
9467
9468 if (firstMenuItem) {
9469 firstMenuItem.focus();
9470 }
9471
9472 break;
9473 }
9474
9475 case 38: // up arrow
9476
9477 case 40:
9478 // down arrow
9479 _this.navigate(direction);
9480
9481 event.preventDefault(); // prevents keys from scrolling page
9482
9483 break;
9484
9485 default:
9486 break;
9487 }
9488 }
9489
9490 break;
9491 }
9492 }
9493 });
9494
9495 var hasFocusOut = 'onfocusout' in window;
9496
9497 _this.manage(on(_this.element, hasFocusOut ? 'focusout' : 'blur', _this._handleEvent, !hasFocusOut));
9498
9499 _this.manage(on(_this.element, 'mouseenter', _this._handleEvent));
9500
9501 _this.manage(on(_this.element, 'mouseleave', _this._handleEvent));
9502
9503 _this.manage(on(_this.element, 'click', _this._handleEvent));
9504
9505 _this.manage(on(_this.element, 'keydown', _this._handleKeyDown));
9506
9507 return _this;
9508 }
9509 /**
9510 * The map associating DOM element and HeaderSubmenu instance.
9511 * @member HeaderSubmenu.components
9512 * @type {WeakMap}
9513 */
9514
9515
9516 _createClass(HeaderSubmenu, null, [{
9517 key: "options",
9518
9519 /**
9520 * The component options.
9521 * If `options` is specified in the constructor,
9522 * {@linkcode HeaderSubmenu.create .create()}, or
9523 * {@linkcode HeaderSubmenu.init .init()},
9524 * properties in this object are overriden for the instance being create and
9525 * how {@linkcode HeaderSubmenu.init .init()} works.
9526 * @member HeaderSubmenu.options
9527 * @type {Object}
9528 * @property {string} selectorInit The data attribute to find side navs.
9529 */
9530 get: function get() {
9531 var prefix = settings_1.prefix;
9532 return {
9533 selectorInit: '[data-header-submenu]',
9534 selectorTrigger: ".".concat(prefix, "--header__menu-title"),
9535 selectorItem: ".".concat(prefix, "--header__menu .").concat(prefix, "--header__menu-item"),
9536 attribExpanded: 'aria-expanded'
9537 };
9538 }
9539 /**
9540 * Enum for navigating backward/forward.
9541 * @readonly
9542 * @member HeaderSubmenu.NAVIGATE
9543 * @type {Object}
9544 * @property {number} BACKWARD Navigating backward.
9545 * @property {number} FORWARD Navigating forward.
9546 */
9547
9548 }]);
9549
9550 return HeaderSubmenu;
9551 }(mixin(createComponent, initComponentBySearch, handles));
9552
9553 _defineProperty(HeaderSubmenu, "components",
9554 /* #__PURE_CLASS_PROPERTY__ */
9555 new WeakMap());
9556
9557 _defineProperty(HeaderSubmenu, "actions",
9558 /* #__PURE_CLASS_PROPERTY__ */
9559 {
9560 CLOSE_SUBMENU: 'CLOSE_SUBMENU',
9561 OPEN_SUBMENU: 'OPEN_SUBMENU',
9562 TOGGLE_SUBMENU_WITH_FOCUS: 'TOGGLE_SUBMENU_WITH_FOCUS',
9563 DELEGATE_TO_FLYOUT_MENU: 'DELEGATE_TO_FLYOUT_MENU'
9564 });
9565
9566 _defineProperty(HeaderSubmenu, "NAVIGATE",
9567 /* #__PURE_CLASS_PROPERTY__ */
9568 {
9569 BACKWARD: -1,
9570 FORWARD: 1
9571 });
9572
9573 var toArray$b = function toArray(arrayLike) {
9574 return Array.prototype.slice.call(arrayLike);
9575 };
9576
9577 var HeaderNav =
9578 /*#__PURE__*/
9579 function (_mixin) {
9580 _inherits(HeaderNav, _mixin);
9581
9582 function HeaderNav(element, options) {
9583 var _this;
9584
9585 _classCallCheck(this, HeaderNav);
9586
9587 _this = _possibleConstructorReturn(this, _getPrototypeOf(HeaderNav).call(this, element, options));
9588
9589 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
9590 var focused = _this.element.ownerDocument.activeElement.closest(_this.options.selectorSubmenu);
9591
9592 return focused && focused.nodeType === Node.ELEMENT_NODE ? focused.querySelector(_this.options.selectorSubmenuLink) : null;
9593 });
9594
9595 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
9596 var items = toArray$b(_this.element.querySelectorAll(_this.options.selectorSubmenuLink));
9597
9598 var start = _this.getCurrentNavigation();
9599
9600 var getNextItem = function getNextItem(old) {
9601 var handleUnderflow = function handleUnderflow(index, length) {
9602 return index + (index >= 0 ? 0 : length);
9603 };
9604
9605 var handleOverflow = function handleOverflow(index, length) {
9606 return index - (index < length ? 0 : length);
9607 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
9608
9609
9610 var index = Math.max(items.indexOf(old) + direction, -1);
9611 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
9612 };
9613
9614 getNextItem(start).focus();
9615 });
9616
9617 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
9618 var keyCodes = {
9619 37: _this.constructor.NAVIGATE.BACKWARD,
9620 // left arrow
9621 39: _this.constructor.NAVIGATE.FORWARD // right arrow
9622
9623 };
9624 var keyCodeMatches = keyCodes[event.which];
9625
9626 if (keyCodeMatches) {
9627 _this.navigate(keyCodeMatches);
9628 }
9629 });
9630
9631 _this.manage(on(_this.element, 'keydown', _this._handleKeyDown));
9632
9633 return _this;
9634 }
9635 /**
9636 * The map associating DOM element and Header instance.
9637 * @member HeaderNav.components
9638 * @type {WeakMap}
9639 */
9640
9641
9642 _createClass(HeaderNav, null, [{
9643 key: "options",
9644
9645 /**
9646 * The component options.
9647 * If `options` is specified in the constructor,
9648 * {@linkcode HeaderNav.create .create()}, or
9649 * {@linkcode HeaderNav.init .init()},
9650 * properties in this object are overriden for the instance being create and
9651 * how {@linkcode HeaderNav.init .init()} works.
9652 * @member HeaderNav.options
9653 * @type {Object}
9654 * @property {string} selectorInit The data attribute to find side navs.
9655 */
9656 get: function get() {
9657 var prefix = settings_1.prefix;
9658 return {
9659 selectorInit: '[data-header-nav]',
9660 selectorNavKind: '[data-header-nav-kind]',
9661 selectorSubmenu: ".".concat(prefix, "--header__submenu"),
9662 selectorSubmenuLink: ".".concat(prefix, "--header__menu-title"),
9663 selectorSubmenuItem: ".".concat(prefix, "--header__menu-title > .").concat(prefix, "--header__menu-item")
9664 };
9665 }
9666 /**
9667 * Enum for navigating backward/forward.
9668 * @readonly
9669 * @member Header.NAVIGATE
9670 * @type {Object}
9671 * @property {number} BACKWARD Navigating backward.
9672 * @property {number} FORWARD Navigating forward.
9673 */
9674
9675 }]);
9676
9677 return HeaderNav;
9678 }(mixin(createComponent, initComponentBySearch, handles));
9679
9680 _defineProperty(HeaderNav, "components",
9681 /* #__PURE_CLASS_PROPERTY__ */
9682 new WeakMap());
9683
9684 _defineProperty(HeaderNav, "NAVIGATE",
9685 /* #__PURE_CLASS_PROPERTY__ */
9686 {
9687 BACKWARD: -1,
9688 FORWARD: 1
9689 });
9690
9691 var NavigationMenuPanel =
9692 /*#__PURE__*/
9693 function (_mixin) {
9694 _inherits(NavigationMenuPanel, _mixin);
9695
9696 function NavigationMenuPanel() {
9697 var _getPrototypeOf2;
9698
9699 var _this;
9700
9701 _classCallCheck(this, NavigationMenuPanel);
9702
9703 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
9704 args[_key] = arguments[_key];
9705 }
9706
9707 _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(NavigationMenuPanel)).call.apply(_getPrototypeOf2, [this].concat(args)));
9708
9709 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "createdByLauncher", function (event) {
9710 var isExpanded = !_this.element.hasAttribute('hidden');
9711 var newState = isExpanded ? 'collapsed' : 'expanded';
9712 _this.triggerButton = event.delegateTarget;
9713
9714 _this.changeState(newState);
9715 });
9716
9717 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "shouldStateBeChanged", function (state) {
9718 return state === 'expanded' === _this.element.hasAttribute('hidden');
9719 });
9720
9721 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
9722 toggleAttribute(_this.element, 'hidden', state !== 'expanded');
9723
9724 if (_this.triggerButton) {
9725 if (state === 'expanded') {
9726 var focusableMenuItems = _this.element.querySelector(_this.options.selectorFocusableMenuItem);
9727
9728 if (focusableMenuItems) {
9729 focusableMenuItems.focus();
9730 }
9731 }
9732
9733 var label = state === 'expanded' ? _this.triggerButton.getAttribute(_this.options.attribLabelCollapse) : _this.triggerButton.getAttribute(_this.options.attribLabelExpand);
9734
9735 _this.triggerButton.classList.toggle(_this.options.classNavigationMenuPanelHeaderActionActive, state === 'expanded');
9736
9737 _this.triggerButton.setAttribute('aria-label', label);
9738
9739 _this.triggerButton.setAttribute('title', label);
9740 }
9741
9742 callback();
9743 });
9744
9745 return _this;
9746 }
9747
9748 _createClass(NavigationMenuPanel, null, [{
9749 key: "options",
9750
9751 /**
9752 * The component options.
9753 * If `options` is specified in the constructor,
9754 * {@linkcode NavigationMenuPanel.create .create()}, or
9755 * {@linkcode NavigationMenuPanel.init .init()},
9756 * properties in this object are overriden for the instance being create and
9757 * how {@linkcode NavigationMenuPanel.init .init()} works.
9758 * @member NavigationMenuPanel.options
9759 * @type {Object}
9760 * @property {string} selectorInit The CSS class to find popup navs.
9761 * @property {string} attribInitTarget The attribute name in the launcher buttons to find target popup nav.
9762 * @property {string[]} initEventNames The events that the component will handles
9763 */
9764 get: function get() {
9765 var prefix = settings_1.prefix;
9766 return {
9767 initEventNames: ['click'],
9768 eventBeforeExpanded: 'navigation-menu-being-expanded',
9769 eventAfterExpanded: 'navigation-menu-expanded',
9770 eventBeforeCollapsed: 'navigation-menu-being-collapsed',
9771 eventAfterCollapsed: 'navigation-menu-collapsed',
9772 selectorFocusableMenuItem: ".".concat(prefix, "--navigation__category-toggle, .").concat(prefix, "--navigation-link"),
9773 classNavigationMenuPanelHeaderActionActive: "".concat(prefix, "--header__action--active"),
9774 attribLabelExpand: 'data-navigation-menu-panel-label-expand',
9775 attribLabelCollapse: 'data-navigation-menu-panel-label-collapse'
9776 };
9777 }
9778 }]);
9779
9780 return NavigationMenuPanel;
9781 }(mixin(createComponent, initComponentByLauncher, exports$1, handles, eventedState));
9782
9783 _defineProperty(NavigationMenuPanel, "components",
9784 /* #__PURE_CLASS_PROPERTY__ */
9785 new WeakMap());
9786
9787 var NavigationMenu =
9788 /*#__PURE__*/
9789 function (_NavigationMenuPanel) {
9790 _inherits(NavigationMenu, _NavigationMenuPanel);
9791
9792 /**
9793 * A navigation menu
9794 * @extends NavigationMenuPanel
9795 * @param {HTMLElement} element The element working as a selector.
9796 * @param {Object} [options] The component options.
9797 * @param {string} [options.selectorInit] The CSS class to find navigation
9798 * menus.
9799 * @param {string} [options.attribInitTarget] The attribute name in the
9800 * launcher buttons to find target navigation menu.
9801 * @param {string} [options.selectorShellNavSubmenu] The CSS selector for a
9802 * nav submenu
9803 * @param {string} [options.selectorShellNavLink] The CSS selector for a nav
9804 * link
9805 * @param {string} [options.selectorShellNavLinkCurrent] The CSS selector for
9806 * the current nav link
9807 * @param {string} [options.selectorShellNavItem] The CSS selector for a nav
9808 * item
9809 * @param {string} [options.selectorShellNavCategory] The CSS selector for a
9810 * nav category
9811 * @param {string} [options.classShellNavItemActive] The CSS class for the
9812 * active nav item
9813 * @param {string} [options.classShellNavLinkCurrent] The CSS class for the
9814 * current lav link
9815 * @param {string} [options.classShellNavCategoryExpanded] The CSS class
9816 * for an expanded nav category
9817 */
9818 function NavigationMenu(element, options) {
9819 var _this;
9820
9821 _classCallCheck(this, NavigationMenu);
9822
9823 _this = _possibleConstructorReturn(this, _getPrototypeOf(NavigationMenu).call(this, element, options));
9824
9825 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
9826 return _this.element.ownerDocument.activeElement;
9827 });
9828
9829 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
9830 var items = _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorFocusableNavItems));
9831
9832 var start = _this.getCurrentNavigation();
9833
9834 var getNextItem = function getNextItem(old) {
9835 var handleUnderflow = function handleUnderflow(index, length) {
9836 return index + (index >= 0 ? 0 : length);
9837 };
9838
9839 var handleOverflow = function handleOverflow(index, length) {
9840 return index - (index < length ? 0 : length);
9841 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
9842
9843
9844 var index = Math.max(items.indexOf(old) + direction, -1);
9845 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
9846 };
9847
9848 getNextItem(start).focus();
9849 });
9850
9851 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
9852 // handle Esc
9853 var isExpanded = !_this.element.hasAttribute('hidden');
9854
9855 if (event.which === 27 && isExpanded) {
9856 _this.changeState('collapsed');
9857
9858 if (_this.triggerButton) {
9859 _this.triggerButton.focus();
9860 }
9861
9862 return;
9863 } // handle up/down arrow keys
9864
9865
9866 var matchesNavSubmenu = eventMatches(event, _this.options.selectorShellNavSubmenu);
9867 var matchesShellNavLink = eventMatches(event, _this.options.selectorShellNavLink);
9868
9869 if (!matchesNavSubmenu && !matchesShellNavLink) {
9870 return;
9871 }
9872
9873 var navigationKeyCodes = {
9874 38: _this.constructor.NAVIGATE.BACKWARD,
9875 // up arrow
9876 40: _this.constructor.NAVIGATE.FORWARD // down arrow
9877
9878 };
9879 var navigationKeyCodeMatches = navigationKeyCodes[event.which];
9880
9881 if (navigationKeyCodeMatches) {
9882 event.preventDefault(); // prevent arrow keys from scrolling
9883
9884 _this.navigate(navigationKeyCodeMatches);
9885 }
9886 });
9887
9888 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusOut", function (event) {
9889 var nextTargetIsOfSelf = _this.element.contains(event.relatedTarget) || event.relatedTarget === _this.triggerButton || !event.relatedTarget;
9890
9891 var oldTargetIsOfSelf = _this.element.contains(event.target);
9892
9893 if (oldTargetIsOfSelf && !nextTargetIsOfSelf) {
9894 _this.changeState('collapsed');
9895
9896 _this.triggerButton.focus();
9897 }
9898 });
9899
9900 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "changeNavSubmenuState", function (_ref) {
9901 var matchesNavSubmenu = _ref.matchesNavSubmenu,
9902 shouldBeCollapsed = _ref.shouldBeCollapsed;
9903 var shellNavCategory = matchesNavSubmenu.closest(_this.options.selectorShellNavCategory);
9904
9905 if (!shellNavCategory) {
9906 return;
9907 }
9908
9909 matchesNavSubmenu.setAttribute('aria-expanded', !shouldBeCollapsed);
9910 shellNavCategory.classList.toggle(_this.options.classShellNavCategoryExpanded);
9911 Array.prototype.forEach.call(shellNavCategory.querySelectorAll(_this.options.selectorShellNavLink), function (item) {
9912 item.tabIndex = !shouldBeCollapsed ? 0 : -1;
9913 });
9914 });
9915
9916 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleClick", function (event) {
9917 var matchesNavSubmenu = eventMatches(event, _this.options.selectorShellNavSubmenu);
9918 var matchesShellNavLink = eventMatches(event, _this.options.selectorShellNavLink);
9919 var matchesNestedShellNavLink = eventMatches(event, _this.options.selectorShellNestedNavLink);
9920
9921 if (!matchesNavSubmenu && !matchesShellNavLink) {
9922 return;
9923 }
9924
9925 if (matchesNestedShellNavLink) {
9926 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorShellNavLinkCurrent)).forEach(function (el) {
9927 el.classList.remove(_this.options.classShellNavItemActive, _this.options.classShellNavLinkCurrent);
9928 });
9929
9930 matchesNestedShellNavLink.closest(_this.options.selectorShellNavNestedCategory).classList.add(_this.options.classShellNavItemActive);
9931 return;
9932 }
9933
9934 if (matchesNavSubmenu) {
9935 var isExpanded = matchesNavSubmenu.getAttribute('aria-expanded') === 'true';
9936
9937 _this.changeNavSubmenuState({
9938 matchesNavSubmenu: matchesNavSubmenu,
9939 isExpanded: isExpanded
9940 });
9941
9942 return;
9943 }
9944
9945 if (matchesShellNavLink) {
9946 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorShellNavLinkCurrent)).forEach(function (el) {
9947 el.classList.remove(_this.options.classShellNavItemActive, _this.options.classShellNavLinkCurrent);
9948 });
9949
9950 matchesShellNavLink.closest(_this.options.selectorShellNavItem).classList.add(_this.options.classShellNavItemActive);
9951 }
9952 });
9953
9954 _this.manage(on(element, 'click', _this._handleClick));
9955
9956 _this.manage(on(element, 'keydown', _this._handleKeyDown));
9957
9958 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
9959 if (!_this.element.hasAttribute('hidden') && !_this.triggerButton.contains(event.target) && !_this.element.contains(event.target)) {
9960 _this.changeState('collapsed');
9961 }
9962 }));
9963
9964 var hasFocusOut = 'onfocusout' in window;
9965
9966 _this.manage(on(_this.element, hasFocusOut ? 'focusout' : 'blur', _this._handleFocusOut, !hasFocusOut));
9967
9968 return _this;
9969 }
9970 /**
9971 * @returns {Element} Currently highlighted element.
9972 */
9973
9974
9975 _createClass(NavigationMenu, null, [{
9976 key: "options",
9977
9978 /**
9979 * The component options.
9980 * If `options` is specified in the constructor,
9981 * {@linkcode NavigationMenu.create .create()}, or
9982 * {@linkcode NavigationMenu.init .init()},
9983 * properties in this object are overriden for the instance being create and
9984 * how {@linkcode NavigationMenu.init .init()} works.
9985 * @member NavigationMenu.options
9986 * @type {Object}
9987 * @property {string} selectorInit The CSS class to find navigation menus.
9988 * @property {string} attribInitTarget The attribute name in the
9989 * launcher buttons to find target navigation menu.
9990 * @property {string[]} initEventNames The events that the component
9991 * will handles
9992 */
9993 get: function get() {
9994 var prefix = settings_1.prefix;
9995 return Object.assign(Object.create(NavigationMenuPanel.options), {
9996 selectorInit: '[data-navigation-menu]',
9997 attribInitTarget: 'data-navigation-menu-target',
9998 selectorShellNavSubmenu: ".".concat(prefix, "--navigation__category-toggle"),
9999 selectorShellNavLink: ".".concat(prefix, "--navigation-link"),
10000 selectorShellNestedNavLink: ".".concat(prefix, "--navigation__category-item > a.").concat(prefix, "--navigation-link"),
10001 selectorShellNavLinkCurrent: ".".concat(prefix, "--navigation-item--active,.").concat(prefix, "--navigation__category-item--active"),
10002 selectorFocusableNavItems: "\n .".concat(prefix, "--navigation__category-toggle,\n .").concat(prefix, "--navigation-item > .").concat(prefix, "--navigation-link,\n .").concat(prefix, "--navigation-link[tabindex=\"0\"]\n "),
10003 selectorShellNavItem: ".".concat(prefix, "--navigation-item"),
10004 selectorShellNavCategory: ".".concat(prefix, "--navigation__category"),
10005 selectorShellNavNestedCategory: ".".concat(prefix, "--navigation__category-item"),
10006 classShellNavItemActive: "".concat(prefix, "--navigation-item--active"),
10007 classShellNavLinkCurrent: "".concat(prefix, "--navigation__category-item--active"),
10008 classShellNavCategoryExpanded: "".concat(prefix, "--navigation__category--expanded")
10009 });
10010 }
10011 /**
10012 * Enum for navigating backward/forward.
10013 * @readonly
10014 * @member NavigationMenuPanel.NAVIGATE
10015 * @type {Object}
10016 * @property {number} BACKWARD Navigating backward.
10017 * @property {number} FORWARD Navigating forward.
10018 */
10019
10020 }]);
10021
10022 return NavigationMenu;
10023 }(NavigationMenuPanel);
10024
10025 _defineProperty(NavigationMenu, "components",
10026 /* #__PURE_CLASS_PROPERTY__ */
10027 new WeakMap());
10028
10029 _defineProperty(NavigationMenu, "NAVIGATE",
10030 /* #__PURE_CLASS_PROPERTY__ */
10031 {
10032 BACKWARD: -1,
10033 FORWARD: 1
10034 });
10035
10036 /**
10037 * Differentiate between keyboard and mouse-triggered focusout/blur events
10038 * @param {Element} node The element to attach event listeners to
10039 * @param {string} name The event name to listen to
10040 * @param {Function} callback The callback function to invoke
10041 * @returns {Handle} The handle to release the attached event handler
10042 */
10043 function onFocusByKeyboard(node, name, callback) {
10044 var hasFocusout = 'onfocusout' in window;
10045 var focusinEventName = hasFocusout ? 'focusin' : 'focus';
10046 var focusoutEventName = hasFocusout ? 'focusout' : 'blur';
10047 /**
10048 * Event types supported by this function
10049 * @type {Object<string, string>}
10050 */
10051
10052 var supportedEvents = {
10053 focus: focusinEventName,
10054 blur: focusoutEventName
10055 };
10056 var eventName = supportedEvents[name];
10057
10058 if (!eventName) {
10059 throw new Error('Unsupported event!');
10060 }
10061
10062 var clicked;
10063
10064 var handleMousedown = function handleMousedown() {
10065 clicked = true;
10066 requestAnimationFrame(function () {
10067 clicked = false;
10068 });
10069 };
10070
10071 var handleFocusin = function handleFocusin(evt) {
10072 if (!clicked) {
10073 callback(evt);
10074 }
10075 };
10076
10077 node.ownerDocument.addEventListener('mousedown', handleMousedown);
10078 node.addEventListener(eventName, handleFocusin, !hasFocusout);
10079 return {
10080 release: function release() {
10081 if (handleFocusin) {
10082 node.removeEventListener(eventName, handleFocusin, !hasFocusout);
10083 handleFocusin = null;
10084 }
10085
10086 if (handleMousedown) {
10087 node.ownerDocument.removeEventListener('mousedown', handleMousedown);
10088 handleMousedown = null;
10089 }
10090
10091 return null;
10092 }
10093 };
10094 }
10095
10096 var ProductSwitcher =
10097 /*#__PURE__*/
10098 function (_NavigationMenuPanel) {
10099 _inherits(ProductSwitcher, _NavigationMenuPanel);
10100
10101 /**
10102 * A navigation menu
10103 * @extends NavigationMenuPanel
10104 * @param {HTMLElement} element The element working as a selector.
10105 * @param {Object} [options] The component options.
10106 * @param {string} [options.selectorInit] The CSS class to find product
10107 * switchers
10108 * @param {string} [options.attribInitTarget] The attribute name in the
10109 * launcher buttons to find target product switcher
10110 * @param {string} [options.classProductSwitcherExpanded] The CSS class
10111 * for an expanded product switcher
10112 */
10113 function ProductSwitcher(element, options) {
10114 var _this;
10115
10116 _classCallCheck(this, ProductSwitcher);
10117
10118 _this = _possibleConstructorReturn(this, _getPrototypeOf(ProductSwitcher).call(this, element, options));
10119
10120 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "current", '');
10121
10122 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "triggerButtonIds", new Set());
10123
10124 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusOut", function (event) {
10125 if (_this.element.contains(event.relatedTarget)) {
10126 return;
10127 }
10128
10129 var currentTriggerButton = _this.element.ownerDocument.getElementById(_this.current);
10130
10131 if (currentTriggerButton && event.relatedTarget && !event.relatedTarget.matches(_this.options.selectorFloatingMenus)) {
10132 currentTriggerButton.focus();
10133 }
10134 });
10135
10136 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
10137 var isExpanded = !_this.element.hasAttribute('hidden');
10138
10139 if (event.which === 27 && isExpanded) {
10140 var triggerButton = _this.current;
10141
10142 _this.changeState(_this.constructor.SELECT_NONE);
10143
10144 _this.element.ownerDocument.getElementById(triggerButton).focus();
10145 }
10146 });
10147
10148 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "createdByLauncher", function (event) {
10149 var isExpanded = _this.element.classList.contains(_this.options.classProductSwitcherExpanded);
10150
10151 var launcher = event.delegateTarget;
10152
10153 if (!launcher.id) {
10154 launcher.id = "__carbon-product-switcher-launcher-".concat(Math.random().toString(36).substr(2));
10155 }
10156
10157 var current = launcher.id;
10158
10159 _this.changeState(isExpanded && _this.current === current ? _this.constructor.SELECT_NONE : current);
10160 });
10161
10162 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "shouldStateBeChanged", function (current) {
10163 return _this.current !== current;
10164 });
10165
10166 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
10167 _this.element.classList.toggle(_this.options.classProductSwitcherExpanded, state !== _this.constructor.SELECT_NONE);
10168
10169 _this.current = state;
10170
10171 if (_this.current !== _this.constructor.SELECT_NONE) {
10172 _this.triggerButtonIds.add(_this.current);
10173 } // deactivate all other trigger buttons
10174
10175
10176 _this.triggerButtonIds.forEach(function (id) {
10177 var button = _this.element.ownerDocument.getElementById(id);
10178
10179 var label = button.getAttribute(_this.options.attribLabelExpand);
10180 button.classList.remove(_this.options.classNavigationMenuPanelHeaderActionActive);
10181 button.setAttribute('aria-label', label);
10182 button.setAttribute('title', label);
10183 }); // set active trigger button attributes
10184
10185
10186 var currentTriggerButton = _this.element.ownerDocument.getElementById(_this.current);
10187
10188 if (currentTriggerButton) {
10189 var label = currentTriggerButton.getAttribute(_this.options.attribLabelCollapse);
10190 currentTriggerButton.classList.toggle(_this.options.classNavigationMenuPanelHeaderActionActive);
10191 currentTriggerButton.setAttribute('aria-label', label);
10192 currentTriggerButton.setAttribute('title', label);
10193 }
10194
10195 if (state !== _this.constructor.SELECT_NONE) {
10196 _this.element.setAttribute('tabindex', '0');
10197
10198 _this.element.focus();
10199 } else {
10200 _this.element.setAttribute('tabindex', '-1');
10201 }
10202
10203 callback();
10204 });
10205
10206 _this.manage(on(element, 'keydown', _this._handleKeyDown));
10207
10208 _this.manage(onFocusByKeyboard(element, 'blur', _this._handleFocusOut));
10209
10210 return _this;
10211 }
10212 /**
10213 * id of currently active trigger button
10214 * @type {string}
10215 */
10216
10217
10218 _createClass(ProductSwitcher, [{
10219 key: "release",
10220 value: function release() {
10221 this.triggerButtonIds.clear();
10222 return _get(_getPrototypeOf(ProductSwitcher.prototype), "release", this).call(this);
10223 }
10224 /**
10225 * The map associating DOM element and ProductSwitcher instance.
10226 * @member ProductSwitcher.components
10227 * @type {WeakMap}
10228 */
10229
10230 }], [{
10231 key: "options",
10232
10233 /**
10234 * The component options.
10235 * If `options` is specified in the constructor,
10236 * {@linkcode ProductSwitcher.create .create()}, or
10237 * {@linkcode ProductSwitcher.init .init()},
10238 * properties in this object are overriden for the instance being create and
10239 * how {@linkcode ProductSwitcher.init .init()} works.
10240 * @member ProductSwitcher.options
10241 * @type {Object}
10242 * @property {string} selectorInit The CSS class to find popup navs.
10243 * @property {string} attribInitTarget The attribute name in the
10244 * launcher buttons to find target popup nav.
10245 * @property {string[]} initEventNames The events that the component
10246 * will handles
10247 */
10248 get: function get$$1() {
10249 var prefix = settings_1.prefix;
10250 return Object.assign(Object.create(NavigationMenuPanel.options), {
10251 selectorInit: '[data-product-switcher]',
10252 selectorFloatingMenus: "\n .".concat(prefix, "--overflow-menu-options,\n .").concat(prefix, "--overflow-menu-options *,\n .").concat(prefix, "--tooltip,\n .").concat(prefix, "--tooltip *,\n .flatpicker-calendar,\n .flatpicker-calendar *\n "),
10253 attribInitTarget: 'data-product-switcher-target',
10254 classProductSwitcherExpanded: "".concat(prefix, "--panel--expanded")
10255 });
10256 }
10257 }]);
10258
10259 return ProductSwitcher;
10260 }(NavigationMenuPanel);
10261
10262 _defineProperty(ProductSwitcher, "SELECT_NONE",
10263 /* #__PURE_CLASS_PROPERTY__ */
10264 '__carbon-product-switcher-launcher-NONE');
10265
10266 _defineProperty(ProductSwitcher, "components",
10267 /* #__PURE_CLASS_PROPERTY__ */
10268 new WeakMap());
10269
10270 var PaginationNav =
10271 /*#__PURE__*/
10272 function (_mixin) {
10273 _inherits(PaginationNav, _mixin);
10274
10275 /**
10276 * Pagination Nav component
10277 * @extends CreateComponent
10278 * @extends InitComponentBySearch
10279 * @extends Handles
10280 * @param {HTMLElement} element The element working as a pagination nav.
10281 */
10282 function PaginationNav(element, options) {
10283 var _this;
10284
10285 _classCallCheck(this, PaginationNav);
10286
10287 _this = _possibleConstructorReturn(this, _getPrototypeOf(PaginationNav).call(this, element, options));
10288
10289 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getActivePageNumber", function () {
10290 var pageNum;
10291
10292 var activePageElement = _this.element.querySelector(_this.options.selectorPageActive);
10293
10294 if (activePageElement) {
10295 pageNum = Number(activePageElement.getAttribute(_this.options.attribPage));
10296 }
10297
10298 return pageNum;
10299 });
10300
10301 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "clearActivePage", function (evt) {
10302 var pageButtonNodeList = _this.element.querySelectorAll(_this.options.selectorPageButton);
10303
10304 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
10305
10306 Array.prototype.forEach.call(pageButtonNodeList, function (el) {
10307 el.classList.remove(_this.options.classActive, _this.options.classDisabled);
10308 el.removeAttribute(_this.options.attribActive);
10309 el.removeAttribute('aria-disabled');
10310 el.removeAttribute('aria-current');
10311 });
10312
10313 if (pageSelectElement) {
10314 pageSelectElement.removeAttribute('aria-current');
10315 var pageSelectElementOptions = pageSelectElement.options;
10316 Array.prototype.forEach.call(pageSelectElementOptions, function (el) {
10317 el.removeAttribute(_this.options.attribActive);
10318 });
10319
10320 if (!evt.target.matches(_this.options.selectorPageSelect)) {
10321 pageSelectElement.classList.remove(_this.options.classActive);
10322 pageSelectElement.value = '';
10323 }
10324 }
10325 });
10326
10327 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleClick", function (evt) {
10328 if (!evt.target.getAttribute('aria-disabled') === true) {
10329 var nextActivePageNumber = _this.getActivePageNumber();
10330
10331 var pageElementNodeList = _this.element.querySelectorAll(_this.options.selectorPageElement);
10332
10333 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
10334
10335 _this.clearActivePage(evt);
10336
10337 if (evt.target.matches(_this.options.selectorPageButton)) {
10338 nextActivePageNumber = Number(evt.target.getAttribute(_this.options.attribPage));
10339 }
10340
10341 if (evt.target.matches(_this.options.selectorPagePrevious)) {
10342 nextActivePageNumber -= 1;
10343 }
10344
10345 if (evt.target.matches(_this.options.selectorPageNext)) {
10346 nextActivePageNumber += 1;
10347 }
10348
10349 var pageTargetElement = pageElementNodeList[nextActivePageNumber - 1];
10350 pageTargetElement.setAttribute(_this.options.attribActive, true);
10351
10352 if (pageTargetElement.tagName === 'OPTION') {
10353 pageSelectElement.value = _this.getActivePageNumber();
10354 pageSelectElement.classList.add(_this.options.classActive);
10355 pageSelectElement.setAttribute('aria-current', 'page');
10356 } else {
10357 pageTargetElement.classList.add(_this.options.classActive, _this.options.classDisabled);
10358 pageTargetElement.setAttribute('aria-disabled', true);
10359 pageTargetElement.setAttribute('aria-current', 'page');
10360 }
10361
10362 _this.setPrevNextStates();
10363 }
10364 });
10365
10366 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleSelectChange", function (evt) {
10367 _this.clearActivePage(evt);
10368
10369 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
10370
10371 var pageSelectElementOptions = pageSelectElement.options;
10372 pageSelectElementOptions[pageSelectElementOptions.selectedIndex].setAttribute(_this.options.attribActive, true);
10373 evt.target.setAttribute('aria-current', 'page');
10374 evt.target.classList.add(_this.options.classActive);
10375
10376 _this.setPrevNextStates();
10377 });
10378
10379 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "setPrevNextStates", function () {
10380 var pageElementNodeList = _this.element.querySelectorAll(_this.options.selectorPageElement);
10381
10382 var totalPages = pageElementNodeList.length;
10383
10384 var pageDirectionElementPrevious = _this.element.querySelector(_this.options.selectorPagePrevious);
10385
10386 var pageDirectionElementNext = _this.element.querySelector(_this.options.selectorPageNext);
10387
10388 if (pageDirectionElementPrevious) {
10389 if (_this.getActivePageNumber() <= 1) {
10390 pageDirectionElementPrevious.setAttribute('aria-disabled', true);
10391 pageDirectionElementPrevious.classList.add(_this.options.classDisabled);
10392 } else {
10393 pageDirectionElementPrevious.removeAttribute('aria-disabled');
10394 pageDirectionElementPrevious.classList.remove(_this.options.classDisabled);
10395 }
10396 }
10397
10398 if (pageDirectionElementNext) {
10399 if (_this.getActivePageNumber() >= totalPages) {
10400 pageDirectionElementNext.setAttribute('aria-disabled', true);
10401 pageDirectionElementNext.classList.add(_this.options.classDisabled);
10402 } else {
10403 pageDirectionElementNext.removeAttribute('aria-disabled');
10404 pageDirectionElementNext.classList.remove(_this.options.classDisabled);
10405 }
10406 }
10407 });
10408
10409 _this.manage(on(_this.element, 'click', function (evt) {
10410 return _this.handleClick(evt);
10411 }));
10412
10413 _this.manage(on(_this.element, 'change', function (evt) {
10414 if (evt.target.matches(_this.options.selectorPageSelect)) {
10415 _this.handleSelectChange(evt);
10416 }
10417 }));
10418
10419 return _this;
10420 }
10421 /**
10422 * Get active page number
10423 */
10424
10425
10426 _createClass(PaginationNav, null, [{
10427 key: "options",
10428
10429 /**
10430 * The component options.
10431 * If `options` is specified in the constructor, {@linkcode PaginationNav.create .create()},
10432 * or {@linkcode PaginationNav.init .init()},
10433 * properties in this object are overriden for the instance being create and how {@linkcode PaginationNav.init .init()} works.
10434 * @member PaginationNav.options
10435 * @type {Object}
10436 * @property {string} selectorInit The data attribute to find pagination nav.
10437 * @property {string} selectorPageElement The data attribute to find page element.
10438 * @property {string} selectorPageButton The data attribute to find page interactive element.
10439 * @property {string} selectorPageDirection The data attribute to find page change element.
10440 * @property {string} selectorPageSelect The data attribute to find page select element.
10441 * @property {string} selectorPageActive The data attribute to find active page element.
10442 * @property {string} [classActive] The CSS class for page's selected state.
10443 * @property {string} [classDisabled] The CSS class for page's disabled state.
10444 */
10445 get: function get() {
10446 var prefix = settings_1.prefix;
10447 return {
10448 selectorInit: '[data-pagination-nav]',
10449 selectorPageElement: '[data-page]',
10450 selectorPageButton: '[data-page-button]',
10451 selectorPagePrevious: '[data-page-previous]',
10452 selectorPageNext: '[data-page-next]',
10453 selectorPageSelect: '[data-page-select]',
10454 selectorPageActive: '[data-page-active="true"]',
10455 attribPage: 'data-page',
10456 attribActive: 'data-page-active',
10457 classActive: "".concat(prefix, "--pagination-nav__page--active"),
10458 classDisabled: "".concat(prefix, "--pagination-nav__page--disabled")
10459 };
10460 }
10461 }]);
10462
10463 return PaginationNav;
10464 }(mixin(createComponent, initComponentBySearch, handles));
10465
10466 _defineProperty(PaginationNav, "components",
10467 /* #__PURE_CLASS_PROPERTY__ */
10468 new WeakMap());
10469
10470 /**
10471 * Copyright IBM Corp. 2016, 2018
10472 *
10473 * This source code is licensed under the Apache-2.0 license found in the
10474 * LICENSE file in the root directory of this source tree.
10475 */
10476
10477 var components = /*#__PURE__*/Object.freeze({
10478 Checkbox: Checkbox,
10479 FileUploader: FileUploader,
10480 ContentSwitcher: ContentSwitcher,
10481 Tab: Tab,
10482 OverflowMenu: OverflowMenu,
10483 Modal: Modal,
10484 Loading: Loading,
10485 InlineLoading: InlineLoading,
10486 Dropdown: Dropdown,
10487 NumberInput: NumberInput,
10488 DataTableV2: DataTableV2,
10489 DatePicker: DatePicker,
10490 Pagination: Pagination,
10491 Search: Search,
10492 Accordion: Accordion,
10493 CopyButton: CopyButton,
10494 Notification: Notification,
10495 Toolbar: Toolbar,
10496 Tooltip: Tooltip,
10497 ProgressIndicator: ProgressIndicator,
10498 FloatingMenu: FloatingMenu,
10499 StructuredList: StructuredList,
10500 Slider: Slider,
10501 Tile: Tile,
10502 CodeSnippet: CodeSnippet,
10503 TextInput: TextInput,
10504 SideNav: SideNav,
10505 HeaderSubmenu: HeaderSubmenu,
10506 HeaderNav: HeaderNav,
10507 NavigationMenu: NavigationMenu,
10508 ProductSwitcher: ProductSwitcher,
10509 PaginationNav: PaginationNav
10510 });
10511
10512 /**
10513 * Copyright IBM Corp. 2016, 2018
10514 *
10515 * This source code is licensed under the Apache-2.0 license found in the
10516 * LICENSE file in the root directory of this source tree.
10517 */
10518 var components$1 = components;
10519 /**
10520 * Instantiates components automatically
10521 * by searching for elements with `data-component-name` (e.g. `data-loading`) attribute
10522 * or upon DOM events (e.g. clicking) on such elements.
10523 * See each components' static `.init()` methods for details.
10524 * @private
10525 */
10526
10527 var init = function init() {
10528 var componentClasses = Object.keys(components$1).map(function (key) {
10529 return components$1[key];
10530 }).filter(function (component) {
10531 return typeof component.init === 'function';
10532 });
10533
10534 if (!settings_1.disableAutoInit) {
10535 componentClasses.forEach(function (Clz) {
10536 var h = Clz.init();
10537 });
10538 }
10539 };
10540
10541 if (document.readyState === 'loading') {
10542 document.addEventListener('DOMContentLoaded', init);
10543 } else {
10544 // DOMContentLoaded has been fired already
10545 // Let consumer have chance to see if it wants automatic instantiation disabled, and then run automatic instantiation otherwise
10546 setTimeout(init, 0);
10547 }
10548
10549 /**
10550 * Copyright IBM Corp. 2016, 2018
10551 *
10552 * This source code is licensed under the Apache-2.0 license found in the
10553 * LICENSE file in the root directory of this source tree.
10554 */
10555
10556 /**
10557 * Copyright IBM Corp. 2016, 2018
10558 *
10559 * This source code is licensed under the Apache-2.0 license found in the
10560 * LICENSE file in the root directory of this source tree.
10561 */
10562 var forEach$1 = Array.prototype.forEach;
10563
10564 var createAndReleaseComponentsUponDOMMutation = function createAndReleaseComponentsUponDOMMutation(records, componentClasses, componentClassesForWatchInit, options) {
10565 records.forEach(function (record) {
10566 forEach$1.call(record.addedNodes, function (node) {
10567 if (node.nodeType === Node.ELEMENT_NODE) {
10568 componentClassesForWatchInit.forEach(function (Clz) {
10569 Clz.init(node, options);
10570 });
10571 }
10572 });
10573 forEach$1.call(record.removedNodes, function (node) {
10574 if (node.nodeType === Node.ELEMENT_NODE) {
10575 componentClasses.forEach(function (Clz) {
10576 if (node.matches(Clz.options.selectorInit)) {
10577 var instance = Clz.components.get(node);
10578
10579 if (instance) {
10580 instance.release();
10581 }
10582 } else {
10583 forEach$1.call(node.querySelectorAll(Clz.options.selectorInit), function (element) {
10584 var instance = Clz.components.get(element);
10585
10586 if (instance) {
10587 instance.release();
10588 }
10589 });
10590 }
10591 });
10592 }
10593 });
10594 });
10595 };
10596 /**
10597 * Automatically instantiates/destroys components in the given element, by watching for DOM additions/removals.
10598 * @param {Node} target The DOM node to instantiate components in. Should be a document or an element.
10599 * @param {Object} [options] The component options.
10600 * @returns {Handle} The handle to stop watching.
10601 */
10602
10603
10604 function watch () {
10605 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
10606 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
10607
10608 if (target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
10609 throw new TypeError('DOM document or DOM element should be given to watch for DOM node to create/release components.');
10610 }
10611
10612 var componentClasses = Object.keys(components).map(function (key) {
10613 return components[key];
10614 }).filter(function (component) {
10615 return typeof component.init === 'function';
10616 });
10617 var handles = componentClasses.map(function (Clz) {
10618 return Clz.init(target, options);
10619 }).filter(Boolean);
10620 var componentClassesForWatchInit = componentClasses.filter(function (Clz) {
10621 return !Clz.forLazyInit;
10622 });
10623 var observer = new MutationObserver(function (records) {
10624 createAndReleaseComponentsUponDOMMutation(records, componentClasses, componentClassesForWatchInit, options);
10625 });
10626 observer.observe(target, {
10627 childList: true,
10628 subtree: true
10629 });
10630 return {
10631 release: function release() {
10632 for (var handle = handles.pop(); handle; handle = handles.pop()) {
10633 handle.release();
10634 }
10635
10636 if (observer) {
10637 observer.disconnect();
10638 observer = null;
10639 }
10640 }
10641 };
10642 }
10643
10644 /**
10645 * Copyright IBM Corp. 2016, 2018
10646 *
10647 * This source code is licensed under the Apache-2.0 license found in the
10648 * LICENSE file in the root directory of this source tree.
10649 */
10650
10651 exports.watch = watch;
10652 exports.settings = settings_1;
10653 exports.Checkbox = Checkbox;
10654 exports.FileUploader = FileUploader;
10655 exports.ContentSwitcher = ContentSwitcher;
10656 exports.Tab = Tab;
10657 exports.OverflowMenu = OverflowMenu;
10658 exports.Modal = Modal;
10659 exports.Loading = Loading;
10660 exports.InlineLoading = InlineLoading;
10661 exports.Dropdown = Dropdown;
10662 exports.NumberInput = NumberInput;
10663 exports.DataTableV2 = DataTableV2;
10664 exports.DatePicker = DatePicker;
10665 exports.Pagination = Pagination;
10666 exports.Search = Search;
10667 exports.Accordion = Accordion;
10668 exports.CopyButton = CopyButton;
10669 exports.Notification = Notification;
10670 exports.Toolbar = Toolbar;
10671 exports.Tooltip = Tooltip;
10672 exports.ProgressIndicator = ProgressIndicator;
10673 exports.FloatingMenu = FloatingMenu;
10674 exports.StructuredList = StructuredList;
10675 exports.Slider = Slider;
10676 exports.Tile = Tile;
10677 exports.CodeSnippet = CodeSnippet;
10678 exports.TextInput = TextInput;
10679 exports.SideNav = SideNav;
10680 exports.HeaderSubmenu = HeaderSubmenu;
10681 exports.HeaderNav = HeaderNav;
10682 exports.NavigationMenu = NavigationMenu;
10683 exports.ProductSwitcher = ProductSwitcher;
10684 exports.PaginationNav = PaginationNav;
10685
10686 return exports;
10687
10688}({}));