UNPKG

473 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 * This file contains the list of the default values of compile-time feature flags.
739 *
740 * Build toolchain can replace variable here and/or the references
741 * in order to apply non-default values to those feature flags.
742 *
743 * @example Render `foo` if `aFeatureFlag` is `true`, render `bar` otherwise.
744 * // `my-component.config.js`
745 * const { aFeatureFlag } = require('/path/to/feature-flags');
746 * ...
747 * module.exports = {
748 * variants: [
749 * {
750 * name: 'default',
751 * label: 'My component',
752 * context: {
753 * aFeatureFlag,
754 * ...
755 * },
756 * },
757 * ...
758 * ],
759 * };
760 *
761 * // `my-component.hbs`
762 * <div>
763 * {{#if aFeatureFlag}}
764 * foo
765 * {{else}}
766 * bar
767 * {{/if}}
768 * </div>
769 *
770 * @example Emit `foo` upon clicking on component's element if `aFeatureFlag` is `true`, emit `bar` otherwise.
771 * import mixin from '/path/to/globals/js/misc/mixin';
772 * import createComponent from '/path/to/globals/js/mixins/create-component';
773 * import initComponentBySearch from '/path/to/globals/js/mixins/init-component-by-search';
774 * import handles from '/path/to/globals/js/mixins/handles';
775 * import on from '/path/to/globals/js/misc/on';
776 *
777 * import { aFeatureFlag } from '/path/to/globals/js/feature-flags';
778 *
779 * class MyClass extends mixin(createComponent, initComponentBySearch, handles) {
780 * constructor(element, options) {
781 * super(element, options);
782 * this.manage(
783 * on(this.element, 'click', () => {
784 * console.log(aFeatureFlag ? 'foo' : 'bar');
785 * })
786 * );
787 * }
788 * }
789 */
790 var breakingChangesX = false;
791
792 /**
793 * Copyright IBM Corp. 2016, 2018
794 *
795 * This source code is licensed under the Apache-2.0 license found in the
796 * LICENSE file in the root directory of this source tree.
797 */
798 function eventedState (ToMix) {
799 /**
800 * Mix-in class to manage events associated with states.
801 * @class EventedState
802 */
803 var EventedState =
804 /*#__PURE__*/
805 function (_ToMix) {
806 _inherits(EventedState, _ToMix);
807
808 function EventedState() {
809 _classCallCheck(this, EventedState);
810
811 return _possibleConstructorReturn(this, _getPrototypeOf(EventedState).apply(this, arguments));
812 }
813
814 _createClass(EventedState, [{
815 key: "_changeState",
816 // eslint-disable-next-line jsdoc/check-param-names
817
818 /**
819 * The internal implementation for {@link EventedState#changeState `.changeState()`}, performing actual change in state.
820 * @param {string} [state] The new state. Can be an omitted, which means toggling.
821 * @param {Object} [detail]
822 * The object that should be put to event details that is fired before/after changing state.
823 * Can have a `group` property, which specifies what state to be changed.
824 * @param {EventedState~changeStateCallback} callback The callback called once changing state is finished or is canceled.
825 * @private
826 */
827 value: function _changeState() {
828 throw new Error('_changeState() should be overriden to perform actual change in state.');
829 } // eslint-disable-next-line jsdoc/check-param-names
830
831 /**
832 * Changes the state of this component.
833 * @param {string} [state] The new state. Can be an omitted, which means toggling.
834 * @param {Object} [detail]
835 * The object that should be put to event details that is fired before/after changing state.
836 * Can have a `group` property, which specifies what state to be changed.
837 * @param {EventedState~changeStateCallback} [callback] The callback called once changing state is finished or is canceled.
838 */
839
840 }, {
841 key: "changeState",
842 value: function changeState() {
843 var _this = this;
844
845 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
846 args[_key] = arguments[_key];
847 }
848
849 var state = typeof args[0] === 'string' ? args.shift() : undefined;
850 var detail = Object(args[0]) === args[0] && typeof args[0] !== 'function' ? args.shift() : undefined;
851 var callback = typeof args[0] === 'function' ? args.shift() : undefined;
852
853 if (typeof this.shouldStateBeChanged === 'function' && !this.shouldStateBeChanged(state, detail)) {
854 if (callback) {
855 callback(null, true);
856 }
857
858 return;
859 }
860
861 var data = {
862 group: detail && detail.group,
863 state: state
864 };
865 var eventNameSuffix = [data.group, state].filter(Boolean).join('-').split('-') // Group or state may contain hyphen
866 .map(function (item) {
867 return item[0].toUpperCase() + item.substr(1);
868 }).join('');
869 var eventStart = new CustomEvent(this.options["eventBefore".concat(eventNameSuffix)], {
870 bubbles: true,
871 cancelable: true,
872 detail: detail
873 });
874 var fireOnNode = detail && detail.delegatorNode || this.element;
875 var canceled = !fireOnNode.dispatchEvent(eventStart);
876
877 if (canceled) {
878 if (callback) {
879 var error = new Error("Changing state (".concat(JSON.stringify(data), ") has been canceled."));
880 error.canceled = true;
881 callback(error);
882 }
883 } else {
884 var changeStateArgs = [state, detail].filter(Boolean);
885
886 this._changeState.apply(this, _toConsumableArray(changeStateArgs).concat([function () {
887 fireOnNode.dispatchEvent(new CustomEvent(_this.options["eventAfter".concat(eventNameSuffix)], {
888 bubbles: true,
889 cancelable: true,
890 detail: detail
891 }));
892
893 if (callback) {
894 callback();
895 }
896 }]));
897 }
898 }
899 /**
900 * Tests if change in state should happen or not.
901 * Classes inheriting {@link EventedState `EventedState`} should override this function.
902 * @function EventedState#shouldStateBeChanged
903 * @param {string} [state] The new state. Can be an omitted, which means toggling.
904 * @param {Object} [detail]
905 * The object that should be put to event details that is fired before/after changing state.
906 * Can have a `group` property, which specifies what state to be changed.
907 * @returns {boolean}
908 * `false` if change in state shouldn't happen, e.g. when the given new state is the same as the current one.
909 */
910
911 }]);
912
913 return EventedState;
914 }(ToMix);
915 /**
916 * The callback called once changing state is finished or is canceled.
917 * @callback EventedState~changeStateCallback
918 * @param {Error} error
919 * An error object with `true` in its `canceled` property if changing state is canceled.
920 * Cancellation happens if the handler of a custom event, that is fired before changing state happens,
921 * calls `.preventDefault()` against the event.
922 * @param {boolean} keptState
923 * `true` if the call to {@link EventedState#changeState `.changeState()`} didn't cause actual change in state.
924 */
925
926
927 return EventedState;
928 }
929
930 /**
931 * Copyright IBM Corp. 2016, 2018
932 *
933 * This source code is licensed under the Apache-2.0 license found in the
934 * LICENSE file in the root directory of this source tree.
935 */
936
937 /**
938 * @param {Event} event The event.
939 * @param {string} selector The selector.
940 * @returns {Element}
941 * The closest ancestor of the event target (or the event target itself) which matches the selectors given in parameter.
942 */
943 function eventMatches(event, selector) {
944 // <svg> in IE does not have `Element#msMatchesSelector()` (that should be copied to `Element#matches()` by a polyfill).
945 // Also a weird behavior is seen in IE where DOM tree seems broken when `event.target` is on <svg>.
946 // Therefore this function simply returns `undefined` when `event.target` is on <svg>.
947 var target = event.target,
948 currentTarget = event.currentTarget;
949
950 if (typeof target.matches === 'function') {
951 if (target.matches(selector)) {
952 // If event target itself matches the given selector, return it
953 return target;
954 }
955
956 if (target.matches("".concat(selector, " *"))) {
957 var closest = target.closest(selector);
958
959 if ((currentTarget.nodeType === Node.DOCUMENT_NODE ? currentTarget.documentElement : currentTarget).contains(closest)) {
960 return closest;
961 }
962 }
963 }
964
965 return undefined;
966 }
967
968 var toArray = function toArray(arrayLike) {
969 return Array.prototype.slice.call(arrayLike);
970 };
971
972 var FileUploader =
973 /*#__PURE__*/
974 function (_mixin) {
975 _inherits(FileUploader, _mixin);
976
977 /**
978 * File uploader.
979 * @extends CreateComponent
980 * @extends InitComponentBySearch
981 * @extends eventedState
982 * @extends Handles
983 * @param {HTMLElement} element The element working as a file uploader.
984 * @param {Object} [options] The component options. See static options.
985 */
986 function FileUploader(element) {
987 var _this;
988
989 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
990
991 _classCallCheck(this, FileUploader);
992
993 _this = _possibleConstructorReturn(this, _getPrototypeOf(FileUploader).call(this, element, options));
994
995 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, detail, callback) {
996 if (state === 'delete-filename-fileuploader') {
997 _this.container.removeChild(detail.filenameElement);
998 }
999
1000 if (typeof callback === 'function') {
1001 callback();
1002 }
1003 });
1004
1005 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleDeleteButton", function (evt) {
1006 var target = eventMatches(evt, "[data-for=".concat(_this.inputId, "]"));
1007
1008 if (target) {
1009 _this._changeState('delete-filename-fileuploader', {
1010 initialEvt: evt,
1011 filenameElement: target.parentNode
1012 });
1013 }
1014 });
1015
1016 _this.input = _this.element.querySelector(_this.options.selectorInput);
1017 _this.container = _this.element.querySelector(_this.options.selectorContainer);
1018
1019 if (!_this.input) {
1020 throw new TypeError('Cannot find the file input box.');
1021 }
1022
1023 if (!_this.container) {
1024 throw new TypeError('Cannot find the file names container.');
1025 }
1026
1027 _this.inputId = _this.input.getAttribute('id');
1028
1029 _this.manage(on(_this.input, 'change', function () {
1030 return _this._displayFilenames();
1031 }));
1032
1033 _this.manage(on(_this.container, 'click', _this._handleDeleteButton));
1034
1035 return _this;
1036 }
1037
1038 _createClass(FileUploader, [{
1039 key: "_filenamesHTML",
1040 value: function _filenamesHTML(name, id) {
1041 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>");
1042 }
1043 }, {
1044 key: "_uploadHTML",
1045 value: function _uploadHTML() {
1046 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>");
1047 }
1048 }, {
1049 key: "_closeButtonHTML",
1050 value: function _closeButtonHTML() {
1051
1052 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>");
1053 }
1054 }, {
1055 key: "_checkmarkHTML",
1056 value: function _checkmarkHTML() {
1057 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>");
1058 }
1059 }, {
1060 key: "_getStateContainers",
1061 value: function _getStateContainers() {
1062 var stateContainers = toArray(this.element.querySelectorAll("[data-for=".concat(this.inputId, "]")));
1063
1064 if (stateContainers.length === 0) {
1065 throw new TypeError('State container elements not found; invoke _displayFilenames() first');
1066 }
1067
1068 if (stateContainers[0].dataset.for !== this.inputId) {
1069 throw new TypeError('File input id must equal [data-for] attribute');
1070 }
1071
1072 return stateContainers;
1073 }
1074 /**
1075 * Inject selected files into DOM. Invoked on change event.
1076 */
1077
1078 }, {
1079 key: "_displayFilenames",
1080 value: function _displayFilenames() {
1081 var _this2 = this;
1082
1083 var container = this.element.querySelector(this.options.selectorContainer);
1084 var HTMLString = toArray(this.input.files).map(function (file) {
1085 return _this2._filenamesHTML(file.name, _this2.inputId);
1086 }).join('');
1087 container.insertAdjacentHTML('afterbegin', HTMLString);
1088 }
1089 }, {
1090 key: "_removeState",
1091 value: function _removeState(element) {
1092 if (!element || element.nodeType !== Node.ELEMENT_NODE) {
1093 throw new TypeError('DOM element should be given to initialize this widget.');
1094 }
1095
1096 while (element.firstChild) {
1097 element.removeChild(element.firstChild);
1098 }
1099 }
1100 }, {
1101 key: "_handleStateChange",
1102 value: function _handleStateChange(elements, selectIndex, html) {
1103 var _this3 = this;
1104
1105 if (selectIndex === undefined) {
1106 elements.forEach(function (el) {
1107 _this3._removeState(el);
1108
1109 el.insertAdjacentHTML('beforeend', html);
1110 });
1111 } else {
1112 elements.forEach(function (el, index) {
1113 if (index === selectIndex) {
1114 _this3._removeState(el);
1115
1116 el.insertAdjacentHTML('beforeend', html);
1117 }
1118 });
1119 }
1120 }
1121 /**
1122 * Handles delete button.
1123 * @param {Event} evt The event triggering this action.
1124 * @private
1125 */
1126
1127 }, {
1128 key: "setState",
1129 value: function setState(state, selectIndex) {
1130 var stateContainers = this._getStateContainers();
1131
1132 if (state === 'edit') {
1133 this._handleStateChange(stateContainers, selectIndex, this._closeButtonHTML());
1134 }
1135
1136 if (state === 'upload') {
1137 this._handleStateChange(stateContainers, selectIndex, this._uploadHTML());
1138 }
1139
1140 if (state === 'complete') {
1141 this._handleStateChange(stateContainers, selectIndex, this._checkmarkHTML());
1142 }
1143 }
1144 /**
1145 * The map associating DOM element and file uploader instance.
1146 * @member FileUploader.components
1147 * @type {WeakMap}
1148 */
1149
1150 }], [{
1151 key: "options",
1152 get: function get() {
1153 var prefix = settings_1.prefix;
1154 return {
1155 selectorInit: '[data-file]',
1156 selectorInput: "input[type=\"file\"].".concat(prefix, "--file-input"),
1157 selectorContainer: '[data-file-container]',
1158 selectorCloseButton: ".".concat(prefix, "--file-close"),
1159 classLoading: "".concat(prefix, "--loading"),
1160 classLoadingSvg: "".concat(prefix, "--loading__svg"),
1161 classFileName: "".concat(prefix, "--file-filename"),
1162 classFileClose: "".concat(prefix, "--file-close"),
1163 classFileComplete: "".concat(prefix, "--file-complete"),
1164 classSelectedFile: "".concat(prefix, "--file__selected-file"),
1165 classStateContainer: "".concat(prefix, "--file__state-container"),
1166 eventBeforeDeleteFilenameFileuploader: 'fileuploader-before-delete-filename',
1167 eventAfterDeleteFilenameFileuploader: 'fileuploader-after-delete-filename'
1168 };
1169 }
1170 }]);
1171
1172 return FileUploader;
1173 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
1174
1175 _defineProperty(FileUploader, "components",
1176 /* #__PURE_CLASS_PROPERTY__ */
1177 new WeakMap());
1178
1179 /**
1180 * Copyright 2014-2015, Facebook, Inc.
1181 * All rights reserved.
1182 *
1183 * This source code is licensed under the BSD-style license found in the
1184 * LICENSE file in the root directory of this source tree. An additional grant
1185 * of patent rights can be found in the PATENTS file in the same directory.
1186 */
1187
1188 function initComponentByEvent (ToMix) {
1189 /**
1190 * Mix-in class to instantiate components upon events.
1191 * @class InitComponentByEvent
1192 */
1193 var InitComponentByEvent =
1194 /*#__PURE__*/
1195 function (_ToMix) {
1196 _inherits(InitComponentByEvent, _ToMix);
1197
1198 function InitComponentByEvent() {
1199 _classCallCheck(this, InitComponentByEvent);
1200
1201 return _possibleConstructorReturn(this, _getPrototypeOf(InitComponentByEvent).apply(this, arguments));
1202 }
1203
1204 _createClass(InitComponentByEvent, null, [{
1205 key: "init",
1206
1207 /**
1208 * `true` suggests that this component is lazily initialized upon an action/event, etc.
1209 * @type {boolean}
1210 */
1211
1212 /**
1213 * Instantiates this component in the given element.
1214 * If the given element indicates that it's an component of this class, instantiates it.
1215 * Otherwise, instantiates this component by clicking on this component in the given node.
1216 * @param {Node} target The DOM node to instantiate this component in. Should be a document or an element.
1217 * @param {Object} [options] The component options.
1218 * @param {string} [options.selectorInit] The CSS selector to find this component.
1219 * @returns {Handle} The handle to remove the event listener to handle clicking.
1220 */
1221 value: function init() {
1222 var _this = this;
1223
1224 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
1225 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1226 var effectiveOptions = Object.assign(Object.create(this.options), options);
1227
1228 if (!target || target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
1229 throw new TypeError('DOM document or DOM element should be given to search for and initialize this widget.');
1230 }
1231
1232 if (target.nodeType === Node.ELEMENT_NODE && target.matches(effectiveOptions.selectorInit)) {
1233 this.create(target, options);
1234 } else {
1235 // To work around non-bubbling `focus` event, use `focusin` event instead of it's available, and "capture mode" otherwise
1236 var hasFocusin = 'onfocusin' in (target.nodeType === Node.ELEMENT_NODE ? target.ownerDocument : target).defaultView;
1237 var handles = effectiveOptions.initEventNames.map(function (name) {
1238 var eventName = name === 'focus' && hasFocusin ? 'focusin' : name;
1239 return on(target, eventName, function (event) {
1240 var element = eventMatches(event, effectiveOptions.selectorInit); // Instantiated components handles events by themselves
1241
1242 if (element && !_this.components.has(element)) {
1243 var component = _this.create(element, options);
1244
1245 if (typeof component.createdByEvent === 'function') {
1246 component.createdByEvent(event);
1247 }
1248 }
1249 }, name === 'focus' && !hasFocusin);
1250 });
1251 return {
1252 release: function release() {
1253 for (var handle = handles.pop(); handle; handle = handles.pop()) {
1254 handle.release();
1255 }
1256 }
1257 };
1258 }
1259
1260 return '';
1261 }
1262 }]);
1263
1264 return InitComponentByEvent;
1265 }(ToMix);
1266
1267 _defineProperty(InitComponentByEvent, "forLazyInit",
1268 /* #__PURE_CLASS_PROPERTY__ */
1269 true);
1270
1271 return InitComponentByEvent;
1272 }
1273
1274 /**
1275 * @param {string} name The component name.
1276 * @returns {Function} A stub of removed component.
1277 */
1278
1279 var removedComponent = function removedComponent(name) {
1280 var _class, _temp;
1281
1282 return _temp = _class =
1283 /*#__PURE__*/
1284 function () {
1285 function _class() {
1286 _classCallCheck(this, _class);
1287 }
1288
1289 _createClass(_class, null, [{
1290 key: "create",
1291 value: function create() {
1292 }
1293 }, {
1294 key: "init",
1295 value: function init() {
1296 }
1297 }]);
1298
1299 return _class;
1300 }(), _defineProperty(_class, "components",
1301 /* #__PURE_CLASS_PROPERTY__ */
1302 new WeakMap()), _defineProperty(_class, "options",
1303 /* #__PURE_CLASS_PROPERTY__ */
1304 {}), _temp;
1305 };
1306
1307 var FabButton =
1308 /*#__PURE__*/
1309 function (_mixin) {
1310 _inherits(FabButton, _mixin);
1311
1312 /**
1313 * Floating action button.
1314 * @extends CreateComponent
1315 * @extends InitComponentByEvent
1316 * @extends Handles
1317 * @param {HTMLElement} element The element working as a floting action button.
1318 */
1319 function FabButton(element) {
1320 var _this;
1321
1322 _classCallCheck(this, FabButton);
1323
1324 _this = _possibleConstructorReturn(this, _getPrototypeOf(FabButton).call(this, element));
1325
1326 _this.manage(on(element, 'click', function (event) {
1327 _this.toggle(event);
1328 }));
1329
1330 return _this;
1331 }
1332 /**
1333 * A method called when this widget is created upon clicking.
1334 * @param {Event} event The event triggering the creation.
1335 */
1336
1337
1338 _createClass(FabButton, [{
1339 key: "createdByEvent",
1340 value: function createdByEvent(event) {
1341 this.toggle(event);
1342 }
1343 /**
1344 * Toggles this floating action button.
1345 * @param {Event} event The event triggering this method.
1346 */
1347
1348 }, {
1349 key: "toggle",
1350 value: function toggle(event) {
1351 if (this.element.tagName === 'A') {
1352 event.preventDefault();
1353 }
1354
1355 if (this.element.dataset.state === 'closed') {
1356 this.element.dataset.state = 'open';
1357 } else {
1358 this.element.dataset.state = 'closed';
1359 }
1360 }
1361 /**
1362 * Instantiates floating action button of the given element.
1363 * @param {HTMLElement} element The element.
1364 */
1365
1366 }], [{
1367 key: "create",
1368 value: function create(element) {
1369 return this.components.get(element) || new this(element);
1370 }
1371 /**
1372 * The map associating DOM element and floating action button instance.
1373 * @member FabButton.components
1374 * @type {WeakMap}
1375 */
1376
1377 }]);
1378
1379 return FabButton;
1380 }(mixin(createComponent, initComponentByEvent, handles));
1381
1382 _defineProperty(FabButton, "components",
1383 /* #__PURE_CLASS_PROPERTY__ */
1384 new WeakMap());
1385
1386 _defineProperty(FabButton, "options",
1387 /* #__PURE_CLASS_PROPERTY__ */
1388 {
1389 selectorInit: '[data-fab]',
1390 initEventNames: ['click']
1391 });
1392
1393 var fab = !breakingChangesX ? FabButton : removedComponent('FabButton');
1394
1395 var toArray$1 = function toArray(arrayLike) {
1396 return Array.prototype.slice.call(arrayLike);
1397 };
1398
1399 var ContentSwitcher =
1400 /*#__PURE__*/
1401 function (_mixin) {
1402 _inherits(ContentSwitcher, _mixin);
1403
1404 /**
1405 * Set of content switcher buttons.
1406 * @extends CreateComponent
1407 * @extends InitComponentBySearch
1408 * @extends EventedState
1409 * @extends Handles
1410 * @param {HTMLElement} element The element working as a set of content switcher buttons.
1411 * @param {Object} [options] The component options.
1412 * @param {string} [options.selectorButton] The CSS selector to find switcher buttons.
1413 * @param {string} [options.selectorButtonSelected] The CSS selector to find the selected switcher button.
1414 * @param {string} [options.classActive] The CSS class for switcher button's selected state.
1415 * @param {string} [options.eventBeforeSelected]
1416 * The name of the custom event fired before a switcher button is selected.
1417 * Cancellation of this event stops selection of content switcher button.
1418 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a switcher button is selected.
1419 */
1420 function ContentSwitcher(element, options) {
1421 var _this;
1422
1423 _classCallCheck(this, ContentSwitcher);
1424
1425 _this = _possibleConstructorReturn(this, _getPrototypeOf(ContentSwitcher).call(this, element, options));
1426
1427 _this.manage(on(_this.element, 'click', function (event) {
1428 _this._handleClick(event);
1429 }));
1430
1431 return _this;
1432 }
1433 /**
1434 * Handles click on content switcher button set.
1435 * If the click is on a content switcher button, activates it.
1436 * @param {Event} event The event triggering this method.
1437 */
1438
1439
1440 _createClass(ContentSwitcher, [{
1441 key: "_handleClick",
1442 value: function _handleClick(event) {
1443 var button = eventMatches(event, this.options.selectorButton);
1444
1445 if (button) {
1446 this.changeState({
1447 group: 'selected',
1448 item: button,
1449 launchingEvent: event
1450 });
1451 }
1452 }
1453 /**
1454 * Internal method of {@linkcode ContentSwitcher#setActive .setActive()}, to select a content switcher button.
1455 * @private
1456 * @param {Object} detail The detail of the event trigging this action.
1457 * @param {HTMLElement} detail.item The button to be selected.
1458 * @param {Function} callback Callback called when change in state completes.
1459 */
1460
1461 }, {
1462 key: "_changeState",
1463 value: function _changeState(_ref, callback) {
1464 var _this2 = this;
1465
1466 var item = _ref.item;
1467 // `options.selectorLink` is not defined in this class itself, code here primary is for inherited classes
1468 var itemLink = item.querySelector(this.options.selectorLink);
1469
1470 if (itemLink) {
1471 toArray$1(this.element.querySelectorAll(this.options.selectorLink)).forEach(function (link) {
1472 if (link !== itemLink) {
1473 link.setAttribute('aria-selected', 'false');
1474 }
1475 });
1476 itemLink.setAttribute('aria-selected', 'true');
1477 }
1478
1479 var selectorButtons = toArray$1(this.element.querySelectorAll(this.options.selectorButton));
1480 selectorButtons.forEach(function (button) {
1481 if (button !== item) {
1482 button.setAttribute('aria-selected', false);
1483 button.classList.toggle(_this2.options.classActive, false);
1484 toArray$1(button.ownerDocument.querySelectorAll(button.dataset.target)).forEach(function (element) {
1485 element.setAttribute('hidden', '');
1486 element.setAttribute('aria-hidden', 'true');
1487 });
1488 }
1489 });
1490 item.classList.toggle(this.options.classActive, true);
1491 item.setAttribute('aria-selected', true);
1492 toArray$1(item.ownerDocument.querySelectorAll(item.dataset.target)).forEach(function (element) {
1493 element.removeAttribute('hidden');
1494 element.setAttribute('aria-hidden', 'false');
1495 });
1496
1497 if (callback) {
1498 callback();
1499 }
1500 }
1501 /**
1502 * Selects a content switcher button.
1503 * If the selected button has `data-target` attribute, DOM elements it points to as a CSS selector will be shown.
1504 * DOM elements associated with unselected buttons in the same way will be hidden.
1505 * @param {HTMLElement} item The button to be selected.
1506 * @param {ChangeState~callback} callback The callback is called once selection is finished
1507 * or is canceled. Will only invoke callback if it's passed in.
1508 */
1509
1510 }, {
1511 key: "setActive",
1512 value: function setActive(item, callback) {
1513 this.changeState({
1514 group: 'selected',
1515 item: item
1516 }, function (error) {
1517 if (error) {
1518 if (callback) {
1519 callback(Object.assign(error, {
1520 item: item
1521 }));
1522 }
1523 } else if (callback) {
1524 callback(null, item);
1525 }
1526 });
1527 }
1528 /**
1529 * The map associating DOM element and content switcher set instance.
1530 * @member ContentSwitcher.components
1531 * @type {WeakMap}
1532 */
1533
1534 }], [{
1535 key: "options",
1536
1537 /**
1538 * The component options.
1539 * If `options` is specified in the constructor,
1540 * {@linkcode ContentSwitcher.create .create()}, or {@linkcode ContentSwitcher.init .init()},
1541 * properties in this object are overriden for the instance being create and how {@linkcode ContentSwitcher.init .init()} works.
1542 * @member ContentSwitcher.options
1543 * @type {Object}
1544 * @property {string} selectorInit The CSS selector to find content switcher button set.
1545 * @property {string} [selectorButton] The CSS selector to find switcher buttons.
1546 * @property {string} [selectorButtonSelected] The CSS selector to find the selected switcher button.
1547 * @property {string} [classActive] The CSS class for switcher button's selected state.
1548 * @property {string} [eventBeforeSelected]
1549 * The name of the custom event fired before a switcher button is selected.
1550 * Cancellation of this event stops selection of content switcher button.
1551 * @property {string} [eventAfterSelected] The name of the custom event fired after a switcher button is selected.
1552 */
1553 get: function get() {
1554 var prefix = settings_1.prefix;
1555 return {
1556 selectorInit: '[data-content-switcher]',
1557 selectorButton: "input[type=\"radio\"], .".concat(prefix, "--content-switcher-btn"),
1558 classActive: "".concat(prefix, "--content-switcher--selected"),
1559 eventBeforeSelected: 'content-switcher-beingselected',
1560 eventAfterSelected: 'content-switcher-selected'
1561 };
1562 }
1563 }]);
1564
1565 return ContentSwitcher;
1566 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
1567
1568 _defineProperty(ContentSwitcher, "components",
1569 /* #__PURE_CLASS_PROPERTY__ */
1570 new WeakMap());
1571
1572 var toArray$2 = function toArray(arrayLike) {
1573 return Array.prototype.slice.call(arrayLike);
1574 };
1575
1576 var Tab =
1577 /*#__PURE__*/
1578 function (_ContentSwitcher) {
1579 _inherits(Tab, _ContentSwitcher);
1580
1581 /**
1582 * Container of tabs.
1583 * @extends ContentSwitcher
1584 * @param {HTMLElement} element The element working as a container of tabs.
1585 * @param {Object} [options] The component options.
1586 * @param {string} [options.selectorMenu] The CSS selector to find the drop down menu used in narrow mode.
1587 * @param {string} [options.selectorTrigger] The CSS selector to find the button to open the drop down menu used in narrow mode.
1588 * @param {string} [options.selectorTriggerText]
1589 * The CSS selector to find the element used in narrow mode showing the selected tab item.
1590 * @param {string} [options.selectorButton] The CSS selector to find tab containers.
1591 * @param {string} [options.selectorButtonSelected] The CSS selector to find the selected tab.
1592 * @param {string} [options.selectorLink] The CSS selector to find the links in tabs.
1593 * @param {string} [options.classActive] The CSS class for tab's selected state.
1594 * @param {string} [options.classHidden] The CSS class for the drop down menu's hidden state used in narrow mode.
1595 * @param {string} [options.eventBeforeSelected]
1596 * The name of the custom event fired before a tab is selected.
1597 * Cancellation of this event stops selection of tab.
1598 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a tab is selected.
1599 */
1600 function Tab(element, options) {
1601 var _this;
1602
1603 _classCallCheck(this, Tab);
1604
1605 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tab).call(this, element, options));
1606
1607 _this.manage(on(_this.element, 'keydown', function (event) {
1608 _this._handleKeyDown(event);
1609 }));
1610
1611 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
1612 _this._handleDocumentClick(event);
1613 }));
1614
1615 var selected = _this.element.querySelector(_this.options.selectorButtonSelected);
1616
1617 if (selected) {
1618 _this._updateTriggerText(selected);
1619 }
1620
1621 return _this;
1622 }
1623 /**
1624 * Internal method of {@linkcode Tab#setActive .setActive()}, to select a tab item.
1625 * @private
1626 * @param {Object} detail The detail of the event trigging this action.
1627 * @param {HTMLElement} detail.item The tab item to be selected.
1628 * @param {Function} callback Callback called when change in state completes.
1629 */
1630
1631
1632 _createClass(Tab, [{
1633 key: "_changeState",
1634 value: function _changeState(detail, callback) {
1635 var _this2 = this;
1636
1637 _get(_getPrototypeOf(Tab.prototype), "_changeState", this).call(this, detail, function (error) {
1638 if (!error) {
1639 _this2._updateTriggerText(detail.item);
1640 }
1641
1642 for (var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1643 data[_key - 1] = arguments[_key];
1644 }
1645
1646 callback.apply(void 0, [error].concat(data));
1647 });
1648 }
1649 /**
1650 * Handles click on tab container.
1651 * * If the click is on a tab, activates it.
1652 * * If the click is on the button to open the drop down menu, does so.
1653 * @param {Event} event The event triggering this method.
1654 */
1655
1656 }, {
1657 key: "_handleClick",
1658 value: function _handleClick(event) {
1659 var button = eventMatches(event, this.options.selectorButton);
1660 var trigger = eventMatches(event, this.options.selectorTrigger);
1661
1662 if (button && !button.classList.contains(this.options.classButtonDisabled)) {
1663 _get(_getPrototypeOf(Tab.prototype), "_handleClick", this).call(this, event);
1664
1665 this._updateMenuState(false);
1666 }
1667
1668 if (trigger) {
1669 this._updateMenuState();
1670 }
1671 }
1672 /**
1673 * Handles click on document.
1674 * @param {Event} event The triggering event.
1675 * @private
1676 */
1677
1678 }, {
1679 key: "_handleDocumentClick",
1680 value: function _handleDocumentClick(event) {
1681 var element = this.element;
1682 var isOfSelf = element.contains(event.target);
1683
1684 if (isOfSelf) {
1685 return;
1686 }
1687
1688 this._updateMenuState(false);
1689 }
1690 /**
1691 * Handles arrow keys on tab container.
1692 * * Left keys are used to go to previous tab.
1693 * * Right keys are used to go to next tab.
1694 * @param {Event} event The event triggering this method.
1695 */
1696
1697 }, {
1698 key: "_handleKeyDown",
1699 value: function _handleKeyDown(event) {
1700 var _this3 = this;
1701
1702 var triggerNode = eventMatches(event, this.options.selectorTrigger);
1703
1704 if (triggerNode) {
1705 if (event.which === 13) {
1706 this._updateMenuState();
1707 }
1708
1709 return;
1710 }
1711
1712 var direction = {
1713 37: this.constructor.NAVIGATE.BACKWARD,
1714 39: this.constructor.NAVIGATE.FORWARD
1715 }[event.which];
1716
1717 if (direction) {
1718 var buttons = toArray$2(this.element.querySelectorAll(this.options.selectorButtonEnabled));
1719 var button = this.element.querySelector(this.options.selectorButtonSelected);
1720 var nextIndex = Math.max(buttons.indexOf(button) + direction, -1
1721 /* For `button` not found in `buttons` */
1722 );
1723 var nextIndexLooped = nextIndex >= 0 && nextIndex < buttons.length ? nextIndex : nextIndex - Math.sign(nextIndex) * buttons.length;
1724 this.setActive(buttons[nextIndexLooped], function (error, item) {
1725 if (item) {
1726 var link = item.querySelector(_this3.options.selectorLink);
1727
1728 if (link) {
1729 link.focus();
1730 }
1731 }
1732 });
1733 event.preventDefault();
1734 }
1735 }
1736 /**
1737 * Shows/hides the drop down menu used in narrow mode.
1738 * @param {boolean} [force] `true` to show the menu, `false` to hide the menu, otherwise toggles the menu.
1739 */
1740
1741 }, {
1742 key: "_updateMenuState",
1743 value: function _updateMenuState(force) {
1744 var menu = this.element.querySelector(this.options.selectorMenu);
1745 var trigger = this.element.querySelector(this.options.selectorTrigger);
1746
1747 if (menu) {
1748 menu.classList.toggle(this.options.classHidden, typeof force === 'undefined' ? force : !force);
1749
1750 if (menu.classList.contains(this.options.classHidden)) {
1751 trigger.classList.remove(this.options.classOpen);
1752 } else {
1753 trigger.classList.add(this.options.classOpen);
1754 }
1755 }
1756 }
1757 /**
1758 * Updates the text indicating the currently selected tab item.
1759 * @param {HTMLElement} target The newly selected tab item.
1760 */
1761
1762 }, {
1763 key: "_updateTriggerText",
1764 value: function _updateTriggerText(target) {
1765 var triggerText = this.element.querySelector(this.options.selectorTriggerText);
1766
1767 if (triggerText) {
1768 triggerText.textContent = target.textContent;
1769 }
1770 }
1771 /**
1772 * The map associating DOM element and tab container instance.
1773 * @member Tab.components
1774 * @type {WeakMap}
1775 */
1776
1777 }], [{
1778 key: "options",
1779
1780 /**
1781 * The component options.
1782 * If `options` is specified in the constructor, {@linkcode ContentSwitcher.create .create()}, or {@linkcode Tab.init .init()},
1783 * properties in this object are overriden for the instance being create and how {@linkcode Tab.init .init()} works.
1784 * @member Tab.options
1785 * @type {Object}
1786 * @property {string} selectorInit The CSS selector to find tab containers.
1787 * @property {string} [selectorMenu] The CSS selector to find the drop down menu used in narrow mode.
1788 * @property {string} [selectorTrigger] The CSS selector to find the button to open the drop down menu used in narrow mode.
1789 * @property {string} [selectorTriggerText]
1790 * The CSS selector to find the element used in narrow mode showing the selected tab item.
1791 * @property {string} [selectorButton] The CSS selector to find tab containers.
1792 * @property {string} [selectorButtonSelected] The CSS selector to find the selected tab.
1793 * @property {string} [selectorLink] The CSS selector to find the links in tabs.
1794 * @property {string} [classActive] The CSS class for tab's selected state.
1795 * @property {string} [classHidden] The CSS class for the drop down menu's hidden state used in narrow mode.
1796 * @property {string} [eventBeforeSelected]
1797 * The name of the custom event fired before a tab is selected.
1798 * Cancellation of this event stops selection of tab.
1799 * @property {string} [eventAfterSelected] The name of the custom event fired after a tab is selected.
1800 */
1801 get: function get$$1() {
1802 var prefix = settings_1.prefix;
1803 return Object.assign(Object.create(ContentSwitcher.options), {
1804 selectorInit: '[data-tabs]',
1805 selectorMenu: ".".concat(prefix, "--tabs__nav"),
1806 selectorTrigger: ".".concat(prefix, "--tabs-trigger"),
1807 selectorTriggerText: ".".concat(prefix, "--tabs-trigger-text"),
1808 selectorButton: ".".concat(prefix, "--tabs__nav-item"),
1809 selectorButtonEnabled: ".".concat(prefix, "--tabs__nav-item:not(.").concat(prefix, "--tabs__nav-item--disabled)"),
1810 selectorButtonSelected: ".".concat(prefix, "--tabs__nav-item--selected"),
1811 selectorLink: ".".concat(prefix, "--tabs__nav-link"),
1812 classActive: "".concat(prefix, "--tabs__nav-item--selected"),
1813 classHidden: "".concat(prefix, "--tabs__nav--hidden"),
1814 classOpen: "".concat(prefix, "--tabs-trigger--open"),
1815 classButtonDisabled: "".concat(prefix, "--tabs__nav-item--disabled"),
1816 eventBeforeSelected: 'tab-beingselected',
1817 eventAfterSelected: 'tab-selected'
1818 });
1819 }
1820 /**
1821 * Enum for navigating backward/forward.
1822 * @readonly
1823 * @member Tab.NAVIGATE
1824 * @type {Object}
1825 * @property {number} BACKWARD Navigating backward.
1826 * @property {number} FORWARD Navigating forward.
1827 */
1828
1829 }]);
1830
1831 return Tab;
1832 }(ContentSwitcher);
1833
1834 _defineProperty(Tab, "components",
1835 /* #__PURE_CLASS_PROPERTY__ */
1836 new WeakMap());
1837
1838 _defineProperty(Tab, "NAVIGATE",
1839 /* #__PURE_CLASS_PROPERTY__ */
1840 {
1841 BACKWARD: -1,
1842 FORWARD: 1
1843 });
1844
1845 /**
1846 * Copyright IBM Corp. 2016, 2018
1847 *
1848 * This source code is licensed under the Apache-2.0 license found in the
1849 * LICENSE file in the root directory of this source tree.
1850 */
1851 function getLaunchingDetails(evt) {
1852 if (!evt || typeof evt === 'function') {
1853 return {
1854 launchingElement: null,
1855 launchingEvent: null
1856 };
1857 }
1858
1859 var launchingElement = evt.delegateTarget || evt.currentTarget || evt;
1860 var launchingEvent = evt.currentTarget && evt;
1861
1862 if (launchingElement && !launchingElement.nodeType) {
1863 throw new TypeError('DOM Node should be given for launching element.');
1864 }
1865
1866 if (launchingEvent && !launchingEvent.type) {
1867 throw new TypeError('DOM event should be given for launching event.');
1868 }
1869
1870 return {
1871 launchingElement: launchingElement,
1872 launchingEvent: launchingEvent
1873 };
1874 }
1875
1876 function eventedShowHideState(ToMix) {
1877 /**
1878 * Mix-in class to launch a floating menu.
1879 * @class EventedShowHideState
1880 */
1881 var EventedShowHideState =
1882 /*#__PURE__*/
1883 function (_ToMix) {
1884 _inherits(EventedShowHideState, _ToMix);
1885
1886 function EventedShowHideState() {
1887 _classCallCheck(this, EventedShowHideState);
1888
1889 return _possibleConstructorReturn(this, _getPrototypeOf(EventedShowHideState).apply(this, arguments));
1890 }
1891
1892 _createClass(EventedShowHideState, [{
1893 key: "show",
1894
1895 /**
1896 */
1897
1898 /**
1899 * Switch to 'shown' state.
1900 * @param [evtOrElem] The launching event or element.
1901 * @param {EventedState~changeStateCallback} [callback] The callback.
1902 */
1903 value: function show(evtOrElem, callback) {
1904 if (!evtOrElem || typeof evtOrElem === 'function') {
1905 callback = evtOrElem; // eslint-disable-line no-param-reassign
1906 }
1907
1908 this.changeState('shown', getLaunchingDetails(evtOrElem), callback);
1909 }
1910 /**
1911 * Switch to 'hidden' state.
1912 * @param [evtOrElem] The launching event or element.
1913 * @param {EventedState~changeStateCallback} [callback] The callback.
1914 */
1915
1916 }, {
1917 key: "hide",
1918 value: function hide(evtOrElem, callback) {
1919 if (!evtOrElem || typeof evtOrElem === 'function') {
1920 callback = evtOrElem; // eslint-disable-line no-param-reassign
1921 }
1922
1923 this.changeState('hidden', getLaunchingDetails(evtOrElem), callback);
1924 }
1925 }]);
1926
1927 return EventedShowHideState;
1928 }(ToMix);
1929
1930 return EventedShowHideState;
1931 }
1932
1933 var exports$1 = [eventedState, eventedShowHideState];
1934
1935 function trackBlur(ToMix) {
1936 var TrackBlur =
1937 /*#__PURE__*/
1938 function (_ToMix) {
1939 _inherits(TrackBlur, _ToMix);
1940
1941 /**
1942 * Mix-in class to add an handler for losing focus.
1943 * @extends Handles
1944 * @param {HTMLElement} element The element working as this component.
1945 * @param {Object} [options] The component options.
1946 */
1947 function TrackBlur(element, options) {
1948 var _this;
1949
1950 _classCallCheck(this, TrackBlur);
1951
1952 _this = _possibleConstructorReturn(this, _getPrototypeOf(TrackBlur).call(this, element, options));
1953 var hasFocusin = 'onfocusin' in window;
1954 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
1955
1956 _this.manage(on(_this.element.ownerDocument, focusinEventName, function (event) {
1957 if (!_this.element.contains(event.target)) {
1958 _this.handleBlur(event);
1959 }
1960 }, !hasFocusin));
1961
1962 return _this;
1963 }
1964 /**
1965 * The method called when this component loses focus.
1966 * @abstract
1967 */
1968
1969
1970 _createClass(TrackBlur, [{
1971 key: "handleBlur",
1972 value: function handleBlur() {
1973 throw new Error('Components inheriting TrackBlur mix-in must implement handleBlur() method.');
1974 }
1975 }]);
1976
1977 return TrackBlur;
1978 }(ToMix);
1979
1980 return TrackBlur;
1981 }
1982
1983 var exports$2 = [handles, trackBlur];
1984
1985 /**
1986 * Copyright IBM Corp. 2016, 2018
1987 *
1988 * This source code is licensed under the Apache-2.0 license found in the
1989 * LICENSE file in the root directory of this source tree.
1990 */
1991 // mdn resize function
1992 var optimizedResize =
1993 /* #__PURE__ */
1994 function optimizedResize() {
1995 var callbacks = [];
1996 var running = false; // run the actual callbacks
1997
1998 function runCallbacks() {
1999 callbacks.forEach(function (callback) {
2000 callback();
2001 });
2002 running = false;
2003 } // fired on resize event
2004
2005
2006 function resize() {
2007 if (!running) {
2008 running = true;
2009 window.requestAnimationFrame(runCallbacks);
2010 }
2011 } // adds callback to loop
2012
2013
2014 function addCallback(callback) {
2015 if (callback) {
2016 var index = callbacks.indexOf(callback);
2017
2018 if (index < 0) {
2019 callbacks.push(callback);
2020 }
2021 }
2022 }
2023
2024 return {
2025 // public method to add additional callback
2026 add: function add(callback) {
2027 if (!callbacks.length) {
2028 window.addEventListener('resize', resize);
2029 }
2030
2031 addCallback(callback);
2032 return {
2033 release: function release() {
2034 var index = callbacks.indexOf(callback);
2035
2036 if (index >= 0) {
2037 callbacks.splice(index, 1);
2038 }
2039 }
2040 };
2041 }
2042 };
2043 }();
2044
2045 /**
2046 * The structure for the position of floating menu.
2047 * @typedef {Object} FloatingMenu~position
2048 * @property {number} left The left position.
2049 * @property {number} top The top position.
2050 * @property {number} right The right position.
2051 * @property {number} bottom The bottom position.
2052 */
2053
2054 /**
2055 * The structure for the size of floating menu.
2056 * @typedef {Object} FloatingMenu~size
2057 * @property {number} width The width.
2058 * @property {number} height The height.
2059 */
2060
2061 /**
2062 * The structure for the position offset of floating menu.
2063 * @typedef {Object} FloatingMenu~offset
2064 * @property {number} top The top position.
2065 * @property {number} left The left position.
2066 */
2067
2068 var DIRECTION_LEFT = 'left';
2069 var DIRECTION_TOP = 'top';
2070 var DIRECTION_RIGHT = 'right';
2071 var DIRECTION_BOTTOM = 'bottom';
2072 /**
2073 * @param {Object} params The parameters.
2074 * @param {FloatingMenu~size} params.menuSize The size of the menu.
2075 * @param {FloatingMenu~position} params.refPosition The position of the triggering element.
2076 * @param {FloatingMenu~offset} [params.offset={ left: 0, top: 0 }] The position offset of the menu.
2077 * @param {string} [params.direction=bottom] The menu direction.
2078 * @param {number} [params.scrollX=0] The scroll position of the viewport.
2079 * @param {number} [params.scrollY=0] The scroll position of the viewport.
2080 * @returns {FloatingMenu~offset} The position of the menu, relative to the top-left corner of the viewport.
2081 * @private
2082 */
2083
2084 var getFloatingPosition = function getFloatingPosition(_ref) {
2085 var _DIRECTION_LEFT$DIREC;
2086
2087 var menuSize = _ref.menuSize,
2088 refPosition = _ref.refPosition,
2089 _ref$offset = _ref.offset,
2090 offset = _ref$offset === void 0 ? {} : _ref$offset,
2091 _ref$direction = _ref.direction,
2092 direction = _ref$direction === void 0 ? DIRECTION_BOTTOM : _ref$direction,
2093 _ref$scrollX = _ref.scrollX,
2094 scrollX = _ref$scrollX === void 0 ? 0 : _ref$scrollX,
2095 _ref$scrollY = _ref.scrollY,
2096 scrollY = _ref$scrollY === void 0 ? 0 : _ref$scrollY;
2097 var _refPosition$left = refPosition.left,
2098 refLeft = _refPosition$left === void 0 ? 0 : _refPosition$left,
2099 _refPosition$top = refPosition.top,
2100 refTop = _refPosition$top === void 0 ? 0 : _refPosition$top,
2101 _refPosition$right = refPosition.right,
2102 refRight = _refPosition$right === void 0 ? 0 : _refPosition$right,
2103 _refPosition$bottom = refPosition.bottom,
2104 refBottom = _refPosition$bottom === void 0 ? 0 : _refPosition$bottom;
2105 var width = menuSize.width,
2106 height = menuSize.height;
2107 var _offset$top = offset.top,
2108 top = _offset$top === void 0 ? 0 : _offset$top,
2109 _offset$left = offset.left,
2110 left = _offset$left === void 0 ? 0 : _offset$left;
2111 var refCenterHorizontal = (refLeft + refRight) / 2;
2112 var refCenterVertical = (refTop + refBottom) / 2;
2113 return (_DIRECTION_LEFT$DIREC = {}, _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_LEFT, {
2114 left: refLeft - width + scrollX - left,
2115 top: refCenterVertical - height / 2 + scrollY + top
2116 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_TOP, {
2117 left: refCenterHorizontal - width / 2 + scrollX + left,
2118 top: refTop - height + scrollY - top
2119 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_RIGHT, {
2120 left: refRight + scrollX + left,
2121 top: refCenterVertical - height / 2 + scrollY + top
2122 }), _defineProperty(_DIRECTION_LEFT$DIREC, DIRECTION_BOTTOM, {
2123 left: refCenterHorizontal - width / 2 + scrollX + left,
2124 top: refBottom + scrollY + top
2125 }), _DIRECTION_LEFT$DIREC)[direction];
2126 };
2127
2128 var FloatingMenu =
2129 /*#__PURE__*/
2130 function (_mixin) {
2131 _inherits(FloatingMenu, _mixin);
2132
2133 /**
2134 * Floating menu.
2135 * @extends CreateComponent
2136 * @extends EventedShowHideState
2137 * @param {HTMLElement} element The element working as a modal dialog.
2138 * @param {Object} [options] The component options.
2139 * @param {string} [options.selectorContainer] The CSS selector to find the container to put this menu in.
2140 * @param {string} [options.attribDirection] The attribute name to specify menu placement direction (top/right/bottom/left).
2141 * @param {string} [options.classShown] The CSS class for shown state, for the menu.
2142 * @param {string} [options.classRefShown] The CSS class for shown state, for the trigger button.
2143 * @param {string} [options.eventBeforeShown]
2144 * The name of the custom event fired before this menu is shown.
2145 * Cancellation of this event stops hiding the menu.
2146 * @param {string} [options.eventAfterShown]
2147 * The name of the custom event telling that menu is sure shown
2148 * without being canceled by the event handler named by `eventBeforeShown` option (`floating-menu-beingshown`).
2149 * @param {string} [options.eventBeforeHidden]
2150 * The name of the custom event fired before this menu is hidden.
2151 * Cancellation of this event stops hiding the menu.
2152 * @param {string} [options.eventAfterHidden]
2153 * The name of the custom event telling that menu is sure hidden
2154 * without being canceled by the event handler named by `eventBeforeHidden` option (`floating-menu-beinghidden`).
2155 * @param {Element} [options.refNode] The launching element of the menu. Used for calculating the geometry of the menu.
2156 * @param {Object} [options.offset] The offset to adjust the geometry of the menu. Should have `top`/`left` properties.
2157 */
2158 function FloatingMenu(element, options) {
2159 var _this;
2160
2161 _classCallCheck(this, FloatingMenu);
2162
2163 _this = _possibleConstructorReturn(this, _getPrototypeOf(FloatingMenu).call(this, element, options));
2164
2165 var attribDirectionValue = _this.element.getAttribute(_this.options.attribDirection);
2166
2167 if (!_this.options.direction) {
2168 _this.options.direction = attribDirectionValue || 'bottom';
2169 }
2170
2171 if (!attribDirectionValue) {
2172 // Update attribute for styling
2173 _this.element.setAttribute(_this.options.attribDirection, _this.options.direction);
2174 }
2175
2176 return _this;
2177 }
2178 /**
2179 * Focuses back on the trigger button if this component loses focus.
2180 */
2181
2182
2183 _createClass(FloatingMenu, [{
2184 key: "handleBlur",
2185 value: function handleBlur(event) {
2186 if (this.element.classList.contains(this.options.classShown)) {
2187 this.changeState('hidden', getLaunchingDetails(event));
2188 var refNode = this.options.refNode;
2189
2190 if (this.element.contains(event.relatedTarget) && refNode && event.target !== refNode) {
2191 HTMLElement.prototype.focus.call(refNode); // SVGElement in IE11 does not have `.focus()` method
2192 }
2193 }
2194 }
2195 /**
2196 * @private
2197 * @returns {Element} The element that this menu should be placed to.
2198 */
2199
2200 }, {
2201 key: "_getContainer",
2202 value: function _getContainer() {
2203 return this.element.closest(this.options.selectorContainer) || this.element.ownerDocument.body;
2204 }
2205 /**
2206 * @private
2207 * @returns {Object} The menu position, with `top` and `left` properties.
2208 */
2209
2210 }, {
2211 key: "_getPos",
2212 value: function _getPos() {
2213 var element = this.element;
2214 var _this$options = this.options,
2215 refNode = _this$options.refNode,
2216 offset = _this$options.offset,
2217 direction = _this$options.direction;
2218
2219 if (!refNode) {
2220 throw new Error('Cannot find the refernce node for positioning floating menu.');
2221 }
2222
2223 return getFloatingPosition({
2224 menuSize: element.getBoundingClientRect(),
2225 refPosition: refNode.getBoundingClientRect(),
2226 offset: typeof offset !== 'function' ? offset : offset(element, direction, refNode),
2227 direction: direction,
2228 scrollX: refNode.ownerDocument.defaultView.pageXOffset,
2229 scrollY: refNode.ownerDocument.defaultView.pageYOffset
2230 });
2231 }
2232 /**
2233 * Sees if the computed style is what this floating menu expects.
2234 * @private
2235 */
2236
2237 }, {
2238 key: "_testStyles",
2239 value: function _testStyles() {
2240 if (!this.options.debugStyle) {
2241 return;
2242 }
2243
2244 var element = this.element;
2245 var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
2246 var styles = {
2247 position: 'absolute',
2248 right: 'auto',
2249 margin: 0
2250 };
2251 Object.keys(styles).forEach(function (key) {
2252 var expected = typeof styles[key] === 'number' ? parseFloat(styles[key]) : styles[key];
2253 var actual = computedStyle.getPropertyValue(key);
2254
2255 if (expected !== actual) {
2256 // eslint-disable-next-line no-console
2257 console.warn("Floating menu component expects ".concat(key, ": ").concat(styles[key], " style."));
2258 }
2259 });
2260 }
2261 /**
2262 * Places the menu.
2263 * @private
2264 */
2265
2266 }, {
2267 key: "_place",
2268 value: function _place() {
2269 var element = this.element;
2270
2271 var _this$_getPos = this._getPos(),
2272 left = _this$_getPos.left,
2273 top = _this$_getPos.top;
2274
2275 element.style.left = "".concat(left, "px");
2276 element.style.top = "".concat(top, "px");
2277
2278 this._testStyles();
2279 }
2280 /**
2281 * @param {string} state The new state.
2282 * @returns {boolean} `true` of the current state is different from the given new state.
2283 */
2284
2285 }, {
2286 key: "shouldStateBeChanged",
2287 value: function shouldStateBeChanged(state) {
2288 return (state === 'shown' || state === 'hidden') && state !== (this.element.classList.contains(this.options.classShown) ? 'shown' : 'hidden');
2289 }
2290 /**
2291 * Changes the shown/hidden state.
2292 * @private
2293 * @param {string} state The new state.
2294 * @param {Object} detail The detail of the event trigging this action.
2295 * @param {Function} callback Callback called when change in state completes.
2296 */
2297
2298 }, {
2299 key: "_changeState",
2300 value: function _changeState(state, detail, callback) {
2301 var _this2 = this;
2302
2303 var shown = state === 'shown';
2304 var _this$options2 = this.options,
2305 refNode = _this$options2.refNode,
2306 classShown = _this$options2.classShown,
2307 classRefShown = _this$options2.classRefShown;
2308
2309 if (!refNode) {
2310 throw new TypeError('Cannot find the refernce node for changing the style.');
2311 }
2312
2313 this.element.classList.toggle(classShown, shown);
2314
2315 if (classRefShown) {
2316 refNode.classList.toggle(classRefShown, shown);
2317 }
2318
2319 if (state === 'shown') {
2320 if (!this.hResize) {
2321 this.hResize = optimizedResize.add(function () {
2322 _this2._place();
2323 });
2324 }
2325
2326 this._getContainer().appendChild(this.element);
2327
2328 this._place(); // IE11 puts focus on elements with `.focus()`, even ones without `tabindex` attribute
2329
2330
2331 if (!this.element.hasAttribute(this.options.attribAvoidFocusOnOpen)) {
2332 (this.element.querySelector(this.options.selectorPrimaryFocus) || this.element).focus();
2333 }
2334 }
2335
2336 if (state === 'hidden' && this.hResize) {
2337 this.hResize.release();
2338 this.hResize = null;
2339 }
2340
2341 callback();
2342 }
2343 }, {
2344 key: "release",
2345 value: function release() {
2346 if (this.hResize) {
2347 this.hResize.release();
2348 this.hResize = null;
2349 }
2350
2351 _get(_getPrototypeOf(FloatingMenu.prototype), "release", this).call(this);
2352 }
2353 }]);
2354
2355 return FloatingMenu;
2356 }(mixin(createComponent, exports$1, exports$2));
2357
2358 _defineProperty(FloatingMenu, "options",
2359 /* #__PURE_CLASS_PROPERTY__ */
2360 {
2361 selectorContainer: '[data-floating-menu-container]',
2362 selectorPrimaryFocus: '[data-floating-menu-primary-focus]',
2363 attribDirection: 'data-floating-menu-direction',
2364 attribAvoidFocusOnOpen: 'data-avoid-focus-on-open',
2365 classShown: '',
2366 // Should be provided from options arg in constructor
2367 classRefShown: '',
2368 // Should be provided from options arg in constructor
2369 eventBeforeShown: 'floating-menu-beingshown',
2370 eventAfterShown: 'floating-menu-shown',
2371 eventBeforeHidden: 'floating-menu-beinghidden',
2372 eventAfterHidden: 'floating-menu-hidden',
2373 refNode: null,
2374 // Should be provided from options arg in constructor
2375 offset: {
2376 left: 0,
2377 top: 0
2378 }
2379 });
2380
2381 _defineProperty(FloatingMenu, "components",
2382 /* #__PURE_CLASS_PROPERTY__ */
2383 new WeakMap());
2384
2385 /**
2386 * The CSS property names of the arrow keyed by the floating menu direction.
2387 * @type {Object<string, string>}
2388 */
2389
2390 var triggerButtonPositionProps =
2391 /* #__PURE__ */
2392 function () {
2393 var _ref;
2394
2395 return _ref = {}, _defineProperty(_ref, DIRECTION_TOP, 'bottom'), _defineProperty(_ref, DIRECTION_BOTTOM, 'top'), _defineProperty(_ref, DIRECTION_LEFT, 'left'), _defineProperty(_ref, DIRECTION_RIGHT, 'right'), _ref;
2396 }();
2397 /**
2398 * Determines how the position of arrow should affect the floating menu position.
2399 * @type {Object<string, number>}
2400 */
2401
2402
2403 var triggerButtonPositionFactors =
2404 /* #__PURE__ */
2405 function () {
2406 var _ref2;
2407
2408 return _ref2 = {}, _defineProperty(_ref2, DIRECTION_TOP, -2), _defineProperty(_ref2, DIRECTION_BOTTOM, -1), _defineProperty(_ref2, DIRECTION_LEFT, -2), _defineProperty(_ref2, DIRECTION_RIGHT, -1), _ref2;
2409 }();
2410 /**
2411 * @param {Element} menuBody The menu body with the menu arrow.
2412 * @param {string} direction The floating menu direction.
2413 * @param {Element} trigger The trigger button.
2414 * @returns {FloatingMenu~offset} The adjustment of the floating menu position, upon the position of the menu arrow.
2415 * @private
2416 */
2417
2418
2419 var getMenuOffset = function getMenuOffset(menuBody, direction, trigger) {
2420 var triggerButtonPositionProp = triggerButtonPositionProps[direction];
2421 var triggerButtonPositionFactor = triggerButtonPositionFactors[direction];
2422
2423 if (!triggerButtonPositionProp || !triggerButtonPositionFactor) {
2424 console.warn('Wrong floating menu direction:', direction); // eslint-disable-line no-console
2425 }
2426
2427 var menuWidth = menuBody.offsetWidth;
2428 var menuHeight = menuBody.offsetHeight;
2429 var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
2430 var values = [triggerButtonPositionProp, 'left', 'width', 'height', 'border-top-width'].reduce(function (o, name) {
2431 return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
2432 }, {});
2433
2434 if (Object.keys(values).every(function (name) {
2435 return !isNaN(values[name]);
2436 })) {
2437 var left = values.left,
2438 width = values.width,
2439 height = values.height,
2440 borderTopWidth = values['border-top-width'];
2441 return {
2442 left: menuWidth / 2 - (left + Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2),
2443 top: Math.sqrt(Math.pow(borderTopWidth, 2) * 2) + triggerButtonPositionFactor * values[triggerButtonPositionProp]
2444 };
2445 }
2446
2447 return undefined;
2448 };
2449
2450 var OverflowMenu =
2451 /*#__PURE__*/
2452 function (_mixin) {
2453 _inherits(OverflowMenu, _mixin);
2454
2455 /**
2456 * Overflow menu.
2457 * @extends CreateComponent
2458 * @extends InitComponentBySearch
2459 * @extends Handles
2460 * @param {HTMLElement} element The element working as a modal dialog.
2461 * @param {Object} [options] The component options.
2462 * @param {string} [options.selectorOptionMenu] The CSS selector to find the menu.
2463 * @param {string} [options.classShown] The CSS class for the shown state, for the trigger UI.
2464 * @param {string} [options.classMenuShown] The CSS class for the shown state, for the menu.
2465 * @param {string} [options.classMenuFlip] The CSS class for the flipped state of the menu.
2466 * @param {Object} [options.objMenuOffset] The offset locating the menu for the non-flipped state.
2467 * @param {Object} [options.objMenuOffsetFlip] The offset locating the menu for the flipped state.
2468 */
2469 function OverflowMenu(element, options) {
2470 var _this;
2471
2472 _classCallCheck(this, OverflowMenu);
2473
2474 _this = _possibleConstructorReturn(this, _getPrototypeOf(OverflowMenu).call(this, element, options));
2475
2476 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
2477 var focused = _this.element.ownerDocument.activeElement;
2478 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(_this.options.selectorItem) ? focused : null;
2479 });
2480
2481 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
2482 var items = _toConsumableArray(_this.element.ownerDocument.querySelectorAll(_this.options.selectorItem));
2483
2484 var start = _this.getCurrentNavigation() || _this.element.querySelector(_this.options.selectorItemSelected);
2485
2486 var getNextItem = function getNextItem(old) {
2487 var handleUnderflow = function handleUnderflow(index, length) {
2488 return index + (index >= 0 ? 0 : length);
2489 };
2490
2491 var handleOverflow = function handleOverflow(index, length) {
2492 return index - (index < length ? 0 : length);
2493 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
2494
2495
2496 var index = Math.max(items.indexOf(old) + direction, -1);
2497 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
2498 };
2499
2500 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
2501 if (!current.matches(_this.options.selectorItemHidden) && !current.parentNode.matches(_this.options.selectorItemHidden) && !current.matches(_this.options.selectorItemSelected)) {
2502 current.focus();
2503 break;
2504 }
2505 }
2506 });
2507
2508 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
2509 _this._handleDocumentClick(event);
2510
2511 _this.wasOpenBeforeClick = undefined;
2512 }));
2513
2514 _this.manage(on(_this.element.ownerDocument, 'keydown', function (event) {
2515 _this._handleKeyPress(event);
2516 }));
2517
2518 _this.manage(on(_this.element, 'mousedown', function () {
2519 _this.wasOpenBeforeClick = element.classList.contains(_this.options.classShown);
2520 }));
2521
2522 return _this;
2523 }
2524 /**
2525 * Changes the shown/hidden state.
2526 * @param {string} state The new state.
2527 * @param {Object} detail The detail of the event trigging this action.
2528 * @param {Function} callback Callback called when change in state completes.
2529 */
2530
2531
2532 _createClass(OverflowMenu, [{
2533 key: "changeState",
2534 value: function changeState(state, detail, callback) {
2535 if (state === 'hidden') {
2536 this.element.setAttribute('aria-expanded', 'false');
2537 } else {
2538 this.element.setAttribute('aria-expanded', 'true');
2539 }
2540
2541 if (!this.optionMenu) {
2542 var optionMenu = this.element.querySelector(this.options.selectorOptionMenu);
2543
2544 if (!optionMenu) {
2545 throw new Error('Cannot find the target menu.');
2546 } // Lazily create a component instance for menu
2547
2548
2549 this.optionMenu = FloatingMenu.create(optionMenu, {
2550 refNode: this.element,
2551 classShown: this.options.classMenuShown,
2552 classRefShown: this.options.classShown,
2553 offset: this.options.objMenuOffset
2554 });
2555 this.children.push(this.optionMenu);
2556 }
2557
2558 if (this.optionMenu.element.classList.contains(this.options.classMenuFlip)) {
2559 this.optionMenu.options.offset = this.options.objMenuOffsetFlip;
2560 } // Delegates the action of changing state to the menu.
2561 // (And thus the before/after shown/hidden events are fired from the menu)
2562
2563
2564 this.optionMenu.changeState(state, Object.assign(detail, {
2565 delegatorNode: this.element
2566 }), callback);
2567 }
2568 /**
2569 * Handles click on document.
2570 * @param {Event} event The triggering event.
2571 * @private
2572 */
2573
2574 }, {
2575 key: "_handleDocumentClick",
2576 value: function _handleDocumentClick(event) {
2577 var element = this.element,
2578 optionMenu = this.optionMenu,
2579 wasOpenBeforeClick = this.wasOpenBeforeClick;
2580 var isOfSelf = element.contains(event.target);
2581 var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
2582 var shouldBeOpen = isOfSelf && !wasOpenBeforeClick;
2583 var state = shouldBeOpen ? 'shown' : 'hidden';
2584
2585 if (isOfSelf) {
2586 if (element.tagName === 'A') {
2587 event.preventDefault();
2588 }
2589
2590 event.delegateTarget = element; // eslint-disable-line no-param-reassign
2591 }
2592
2593 if (!isOfMenu || eventMatches(event, this.options.selectorItem)) {
2594 this.changeState(state, getLaunchingDetails(event), function () {
2595 if (state === 'hidden' && isOfMenu) {
2596 element.focus();
2597 }
2598 });
2599 }
2600 }
2601 /**
2602 * Provides the element to move focus from
2603 * @returns {Element} Currently highlighted element.
2604 */
2605
2606 }, {
2607 key: "_handleKeyPress",
2608
2609 /**
2610 * Handles key press on document.
2611 * @param {Event} event The triggering event.
2612 * @private
2613 */
2614 value: function _handleKeyPress(event) {
2615 var key = event.which;
2616 var element = this.element,
2617 optionMenu = this.optionMenu,
2618 options = this.options;
2619 var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
2620 var isExpanded = this.element.classList.contains(this.options.classShown);
2621
2622 switch (key) {
2623 // Esc
2624 case 27:
2625 this.changeState('hidden', getLaunchingDetails(event), function () {
2626 if (isOfMenu) {
2627 element.focus();
2628 }
2629 });
2630 break;
2631 // Enter || Space bar
2632
2633 case 13:
2634 case 32:
2635 {
2636 if (!isExpanded && this.element.ownerDocument.activeElement !== this.element) {
2637 return;
2638 }
2639
2640 var isOfSelf = element.contains(event.target);
2641 var shouldBeOpen = isOfSelf && !element.classList.contains(options.classShown);
2642 var state = shouldBeOpen ? 'shown' : 'hidden';
2643
2644 if (isOfSelf) {
2645 event.delegateTarget = element; // eslint-disable-line no-param-reassign
2646
2647 event.preventDefault(); // prevent scrolling
2648
2649 this.changeState(state, getLaunchingDetails(event), function () {
2650 if (state === 'hidden' && isOfMenu) {
2651 element.focus();
2652 }
2653 });
2654 }
2655
2656 break;
2657 }
2658
2659 case 38: // up arrow
2660
2661 case 40:
2662 // down arrow
2663 {
2664 if (!isExpanded) {
2665 return;
2666 }
2667
2668 event.preventDefault(); // prevent scrolling
2669
2670 var direction = {
2671 38: -1,
2672 40: 1
2673 }[event.which];
2674 this.navigate(direction);
2675 }
2676 break;
2677
2678 default:
2679 break;
2680 }
2681 }
2682 }], [{
2683 key: "options",
2684 get: function get() {
2685 var prefix = settings_1.prefix;
2686 return {
2687 selectorInit: '[data-overflow-menu]',
2688 selectorOptionMenu: ".".concat(prefix, "--overflow-menu-options"),
2689 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 "),
2690 classShown: "".concat(prefix, "--overflow-menu--open"),
2691 classMenuShown: "".concat(prefix, "--overflow-menu-options--open"),
2692 classMenuFlip: "".concat(prefix, "--overflow-menu--flip"),
2693 objMenuOffset: getMenuOffset,
2694 objMenuOffsetFlip: getMenuOffset
2695 };
2696 }
2697 }]);
2698
2699 return OverflowMenu;
2700 }(mixin(createComponent, initComponentBySearch, exports$1, handles));
2701
2702 _defineProperty(OverflowMenu, "components",
2703 /* #__PURE_CLASS_PROPERTY__ */
2704 new WeakMap());
2705
2706 function initComponentByLauncher (ToMix) {
2707 /**
2708 * Mix-in class to instantiate components events on launcher button.
2709 * @class InitComponentByLauncher
2710 */
2711 var InitComponentByLauncher =
2712 /*#__PURE__*/
2713 function (_ToMix) {
2714 _inherits(InitComponentByLauncher, _ToMix);
2715
2716 function InitComponentByLauncher() {
2717 _classCallCheck(this, InitComponentByLauncher);
2718
2719 return _possibleConstructorReturn(this, _getPrototypeOf(InitComponentByLauncher).apply(this, arguments));
2720 }
2721
2722 _createClass(InitComponentByLauncher, null, [{
2723 key: "init",
2724
2725 /**
2726 * `true` suggests that this component is lazily initialized upon an action/event, etc.
2727 * @type {boolean}
2728 */
2729
2730 /**
2731 * Instantiates this component in the given element.
2732 * If the given element indicates that it's an component of this class, instantiates it.
2733 * Otherwise, instantiates this component by clicking on launcher buttons
2734 * (buttons with attribute that `options.attribInitTarget` points to) of this component in the given node.
2735 * @param {Node} target The DOM node to instantiate this component in. Should be a document or an element.
2736 * @param {Object} [options] The component options.
2737 * @param {string} [options.selectorInit] The CSS selector to find this component.
2738 * @param {string} [options.attribInitTarget] The attribute name in the launcher buttons to find target component.
2739 * @returns {Handle} The handle to remove the event listener to handle clicking.
2740 */
2741 value: function init() {
2742 var _this = this;
2743
2744 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
2745 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2746 var effectiveOptions = Object.assign(Object.create(this.options), options);
2747
2748 if (!target || target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
2749 throw new TypeError('DOM document or DOM element should be given to search for and initialize this widget.');
2750 }
2751
2752 if (target.nodeType === Node.ELEMENT_NODE && target.matches(effectiveOptions.selectorInit)) {
2753 this.create(target, options);
2754 } else {
2755 var handles = effectiveOptions.initEventNames.map(function (name) {
2756 return on(target, name, function (event) {
2757 var launcher = eventMatches(event, "[".concat(effectiveOptions.attribInitTarget, "]"));
2758
2759 if (launcher) {
2760 event.delegateTarget = launcher; // eslint-disable-line no-param-reassign
2761
2762 var elements = launcher.ownerDocument.querySelectorAll(launcher.getAttribute(effectiveOptions.attribInitTarget));
2763
2764 if (elements.length > 1) {
2765 throw new Error('Target widget must be unique.');
2766 }
2767
2768 if (elements.length === 1) {
2769 if (launcher.tagName === 'A') {
2770 event.preventDefault();
2771 }
2772
2773 var component = _this.create(elements[0], options);
2774
2775 if (typeof component.createdByLauncher === 'function') {
2776 component.createdByLauncher(event);
2777 }
2778 }
2779 }
2780 });
2781 });
2782 return {
2783 release: function release() {
2784 for (var handle = handles.pop(); handle; handle = handles.pop()) {
2785 handle.release();
2786 }
2787 }
2788 };
2789 }
2790
2791 return '';
2792 }
2793 }]);
2794
2795 return InitComponentByLauncher;
2796 }(ToMix);
2797
2798 _defineProperty(InitComponentByLauncher, "forLazyInit",
2799 /* #__PURE_CLASS_PROPERTY__ */
2800 true);
2801
2802 return InitComponentByLauncher;
2803 }
2804
2805 var Modal =
2806 /*#__PURE__*/
2807 function (_mixin) {
2808 _inherits(Modal, _mixin);
2809
2810 /**
2811 * Modal dialog.
2812 * @extends CreateComponent
2813 * @extends InitComponentByLauncher
2814 * @extends EventedShowHideState
2815 * @extends Handles
2816 * @param {HTMLElement} element The element working as a modal dialog.
2817 * @param {Object} [options] The component options.
2818 * @param {string} [options.classVisible] The CSS class for the visible state.
2819 * @param {string} [options.eventBeforeShown]
2820 * The name of the custom event fired before this modal is shown.
2821 * Cancellation of this event stops showing the modal.
2822 * @param {string} [options.eventAfterShown]
2823 * The name of the custom event telling that modal is sure shown
2824 * without being canceled by the event handler named by `eventBeforeShown` option (`modal-beingshown`).
2825 * @param {string} [options.eventBeforeHidden]
2826 * The name of the custom event fired before this modal is hidden.
2827 * Cancellation of this event stops hiding the modal.
2828 * @param {string} [options.eventAfterHidden]
2829 * The name of the custom event telling that modal is sure hidden
2830 * without being canceled by the event handler named by `eventBeforeHidden` option (`modal-beinghidden`).
2831 */
2832 function Modal(element, options) {
2833 var _this;
2834
2835 _classCallCheck(this, Modal);
2836
2837 _this = _possibleConstructorReturn(this, _getPrototypeOf(Modal).call(this, element, options));
2838
2839 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusinListener", void 0);
2840
2841 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeydownListener", void 0);
2842
2843 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusin", function (evt) {
2844 if (_this.element.classList.contains(_this.options.classVisible) && !_this.element.contains(evt.target) && _this.options.selectorsFloatingMenus.every(function (selector) {
2845 return !eventMatches(evt, selector);
2846 })) {
2847 _this.element.focus();
2848 }
2849 });
2850
2851 _this._hookCloseActions();
2852
2853 return _this;
2854 }
2855 /**
2856 * The handle for `focusin` event listener.
2857 * Used for "focus-wrap" feature.
2858 * @type {Handle}
2859 * @private
2860 */
2861
2862
2863 _createClass(Modal, [{
2864 key: "createdByLauncher",
2865
2866 /**
2867 * A method that runs when `.init()` is called from `initComponentByLauncher`.
2868 * @param {Event} evt The event fired on the launcher button.
2869 */
2870 value: function createdByLauncher(evt) {
2871 this.show(evt);
2872 }
2873 /**
2874 * Determines whether or not to emit events and callback function when `.changeState()` is called from `eventedState`.
2875 * @param {string} state The new state.
2876 * @returns {boolean} `true` if the given `state` is different from current state.
2877 */
2878
2879 }, {
2880 key: "shouldStateBeChanged",
2881 value: function shouldStateBeChanged(state) {
2882 if (state === 'shown') {
2883 return !this.element.classList.contains(this.options.classVisible);
2884 }
2885
2886 return this.element.classList.contains(this.options.classVisible);
2887 }
2888 /**
2889 * Changes the shown/hidden state.
2890 * @private
2891 * @param {string} state The new state.
2892 * @param {Object} detail The detail data to be included in the event that will be fired.
2893 * @param {Function} callback Callback called when change in state completes.
2894 */
2895
2896 }, {
2897 key: "_changeState",
2898 value: function _changeState(state, detail, callback) {
2899 var _this2 = this;
2900
2901 var handleTransitionEnd;
2902
2903 var transitionEnd = function transitionEnd() {
2904 if (handleTransitionEnd) {
2905 handleTransitionEnd = _this2.unmanage(handleTransitionEnd).release();
2906 }
2907
2908 if (state === 'shown' && _this2.element.offsetWidth > 0 && _this2.element.offsetHeight > 0) {
2909 (_this2.element.querySelector(_this2.options.selectorPrimaryFocus) || _this2.element).focus();
2910 }
2911
2912 callback();
2913 };
2914
2915 if (this._handleFocusinListener) {
2916 this._handleFocusinListener = this.unmanage(this._handleFocusinListener).release();
2917 }
2918
2919 if (state === 'shown') {
2920 var hasFocusin = 'onfocusin' in this.element.ownerDocument.defaultView;
2921 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
2922 this._handleFocusinListener = this.manage(on(this.element.ownerDocument, focusinEventName, this._handleFocusin, !hasFocusin));
2923 }
2924
2925 if (state === 'hidden') {
2926 this.element.classList.toggle(this.options.classVisible, false);
2927 } else if (state === 'shown') {
2928 this.element.classList.toggle(this.options.classVisible, true);
2929 }
2930
2931 handleTransitionEnd = this.manage(on(this.element, 'transitionend', transitionEnd));
2932 }
2933 }, {
2934 key: "_hookCloseActions",
2935 value: function _hookCloseActions() {
2936 var _this3 = this;
2937
2938 this.manage(on(this.element, 'click', function (evt) {
2939 var closeButton = eventMatches(evt, _this3.options.selectorModalClose);
2940
2941 if (closeButton) {
2942 evt.delegateTarget = closeButton; // eslint-disable-line no-param-reassign
2943 }
2944
2945 if (closeButton || evt.target === _this3.element) {
2946 _this3.hide(evt);
2947 }
2948 }));
2949
2950 if (this._handleKeydownListener) {
2951 this._handleKeydownListener = this.unmanage(this._handleKeydownListener).release();
2952 }
2953
2954 this._handleKeydownListener = this.manage(on(this.element.ownerDocument.body, 'keydown', function (evt) {
2955 if (evt.which === 27) {
2956 evt.stopPropagation();
2957
2958 _this3.hide(evt);
2959 }
2960 }));
2961 }
2962 /**
2963 * Handles `focusin` (or `focus` depending on browser support of `focusin`) event to do wrap-focus behavior.
2964 * @param {Event} evt The event.
2965 * @private
2966 */
2967
2968 }], [{
2969 key: "options",
2970
2971 /**
2972 * The component options.
2973 * If `options` is specified in the constructor, {@linkcode Modal.create .create()}, or {@linkcode Modal.init .init()},
2974 * properties in this object are overriden for the instance being create and how {@linkcode Modal.init .init()} works.
2975 * @member Modal.options
2976 * @type {Object}
2977 * @property {string} selectorInit The CSS class to find modal dialogs.
2978 * @property {string} [selectorModalClose] The selector to find elements that close the modal.
2979 * @property {string} [selectorPrimaryFocus] The CSS selector to determine the element to put focus when modal gets open.
2980 * @property {string} attribInitTarget The attribute name in the launcher buttons to find target modal dialogs.
2981 * @property {string[]} [selectorsFloatingMenu]
2982 * The CSS selectors of floating menus.
2983 * Used for detecting if focus-wrap behavior should be disabled temporarily.
2984 * @property {string} [classVisible] The CSS class for the visible state.
2985 * @property {string} [classNoScroll] The CSS class for hiding scroll bar in body element while modal is shown.
2986 * @property {string} [eventBeforeShown]
2987 * The name of the custom event fired before this modal is shown.
2988 * Cancellation of this event stops showing the modal.
2989 * @property {string} [eventAfterShown]
2990 * The name of the custom event telling that modal is sure shown
2991 * without being canceled by the event handler named by `eventBeforeShown` option (`modal-beingshown`).
2992 * @property {string} [eventBeforeHidden]
2993 * The name of the custom event fired before this modal is hidden.
2994 * Cancellation of this event stops hiding the modal.
2995 * @property {string} [eventAfterHidden]
2996 * The name of the custom event telling that modal is sure hidden
2997 * without being canceled by the event handler named by `eventBeforeHidden` option (`modal-beinghidden`).
2998 */
2999 get: function get() {
3000 var prefix = settings_1.prefix;
3001 return {
3002 selectorInit: '[data-modal]',
3003 selectorModalClose: '[data-modal-close]',
3004 selectorPrimaryFocus: '[data-modal-primary-focus]',
3005 selectorsFloatingMenus: [".".concat(prefix, "--overflow-menu-options"), ".".concat(prefix, "--tooltip"), '.flatpickr-calendar'],
3006 classVisible: 'is-visible',
3007 attribInitTarget: 'data-modal-target',
3008 initEventNames: ['click'],
3009 eventBeforeShown: 'modal-beingshown',
3010 eventAfterShown: 'modal-shown',
3011 eventBeforeHidden: 'modal-beinghidden',
3012 eventAfterHidden: 'modal-hidden'
3013 };
3014 }
3015 }]);
3016
3017 return Modal;
3018 }(mixin(createComponent, initComponentByLauncher, exports$1, handles));
3019
3020 _defineProperty(Modal, "components",
3021 /* #__PURE_CLASS_PROPERTY__ */
3022 new WeakMap());
3023
3024 var Loading =
3025 /*#__PURE__*/
3026 function (_mixin) {
3027 _inherits(Loading, _mixin);
3028
3029 /**
3030 * Spinner indicating loading state.
3031 * @extends CreateComponent
3032 * @extends InitComponentBySearch
3033 * @extends Handles
3034 * @param {HTMLElement} element The element working as a spinner.
3035 * @param {Object} [options] The component options.
3036 * @param {boolean} [options.active] `true` if this spinner should roll.
3037 */
3038 function Loading(element, options) {
3039 var _this;
3040
3041 _classCallCheck(this, Loading);
3042
3043 _this = _possibleConstructorReturn(this, _getPrototypeOf(Loading).call(this, element, options));
3044 _this.active = _this.options.active; // Initialize spinner
3045
3046 _this.set(_this.active);
3047
3048 return _this;
3049 }
3050 /**
3051 * Sets active/inactive state.
3052 * @param {boolean} active `true` if this spinner should roll.
3053 */
3054
3055
3056 _createClass(Loading, [{
3057 key: "set",
3058 value: function set(active) {
3059 if (typeof active !== 'boolean') {
3060 throw new TypeError('set expects a boolean.');
3061 }
3062
3063 this.active = active;
3064 this.element.classList.toggle(this.options.classLoadingStop, !this.active);
3065 /**
3066 * If overlay is the parentNode then toggle it too.
3067 */
3068
3069 var parentNode = this.element.parentNode;
3070
3071 if (parentNode && parentNode.classList.contains(this.options.classLoadingOverlay)) {
3072 parentNode.classList.toggle(this.options.classLoadingOverlayStop, !this.active);
3073 }
3074
3075 return this;
3076 }
3077 /**
3078 * Toggles active/inactive state.
3079 */
3080
3081 }, {
3082 key: "toggle",
3083 value: function toggle() {
3084 return this.set(!this.active);
3085 }
3086 /**
3087 * @returns {boolean} `true` if this spinner is rolling.
3088 */
3089
3090 }, {
3091 key: "isActive",
3092 value: function isActive() {
3093 return this.active;
3094 }
3095 /**
3096 * Sets state to inactive and deletes the loading element.
3097 */
3098
3099 }, {
3100 key: "end",
3101 value: function end() {
3102 var _this2 = this;
3103
3104 this.set(false);
3105 var handleAnimationEnd = this.manage(on(this.element, 'animationend', function (evt) {
3106 if (handleAnimationEnd) {
3107 handleAnimationEnd = _this2.unmanage(handleAnimationEnd).release();
3108 }
3109
3110 if (evt.animationName === 'rotate-end-p2') {
3111 _this2._deleteElement();
3112 }
3113 }));
3114 }
3115 /**
3116 * Delete component from the DOM.
3117 */
3118
3119 }, {
3120 key: "_deleteElement",
3121 value: function _deleteElement() {
3122 var parentNode = this.element.parentNode;
3123 parentNode.removeChild(this.element);
3124
3125 if (parentNode.classList.contains(this.options.selectorLoadingOverlay)) {
3126 parentNode.remove();
3127 }
3128 }
3129 /**
3130 * The map associating DOM element and spinner instance.
3131 * @member Loading.components
3132 * @type {WeakMap}
3133 */
3134
3135 }], [{
3136 key: "options",
3137
3138 /**
3139 * The component options.
3140 * If `options` is specified in the constructor, {@linkcode Loading.create .create()}, or {@linkcode Loading.init .init()},
3141 * properties in this object are overriden for the instance being create and how {@linkcode Loading.init .init()} works.
3142 * @member Loading.options
3143 * @type {Object}
3144 * @property {string} selectorInit The CSS selector to find spinners.
3145 */
3146 get: function get() {
3147 var prefix = settings_1.prefix;
3148 return {
3149 selectorInit: '[data-loading]',
3150 selectorLoadingOverlay: ".".concat(prefix, "--loading-overlay"),
3151 classLoadingOverlay: "".concat(prefix, "--loading-overlay"),
3152 classLoadingStop: "".concat(prefix, "--loading--stop"),
3153 classLoadingOverlayStop: "".concat(prefix, "--loading-overlay--stop"),
3154 active: true
3155 };
3156 }
3157 }]);
3158
3159 return Loading;
3160 }(mixin(createComponent, initComponentBySearch, handles));
3161
3162 _defineProperty(Loading, "components",
3163 /* #__PURE_CLASS_PROPERTY__ */
3164 new WeakMap());
3165
3166 /**
3167 * Copyright IBM Corp. 2016, 2018
3168 *
3169 * This source code is licensed under the Apache-2.0 license found in the
3170 * LICENSE file in the root directory of this source tree.
3171 */
3172
3173 /**
3174 * Toggles the given attribute of the given element.
3175 * @param {Element} elem The element.
3176 * @param {string} name The attribute name.
3177 * @param {boolean} add `true` to set the attribute.
3178 */
3179 function toggleAttribute(elem, name, add) {
3180 if (add) {
3181 elem.setAttribute(name, '');
3182 } else {
3183 elem.removeAttribute(name);
3184 }
3185 }
3186
3187 var InlineLoading =
3188 /*#__PURE__*/
3189 function (_mixin) {
3190 _inherits(InlineLoading, _mixin);
3191
3192 /**
3193 * Spinner indicating loading state.
3194 * @extends CreateComponent
3195 * @extends InitComponentBySearch
3196 * @extends Handles
3197 * @param {HTMLElement} element The element working as a spinner.
3198 * @param {Object} [options] The component options.
3199 * @param {string} [options.initialState] The initial state, should be `inactive`, `active` or `finished`.
3200 */
3201 function InlineLoading(element, options) {
3202 var _this;
3203
3204 _classCallCheck(this, InlineLoading);
3205
3206 _this = _possibleConstructorReturn(this, _getPrototypeOf(InlineLoading).call(this, element, options)); // Sets the initial state
3207
3208 var initialState = _this.options.initialState;
3209
3210 if (initialState) {
3211 _this.setState(initialState);
3212 }
3213
3214 return _this;
3215 }
3216 /**
3217 * Sets active/inactive state.
3218 * @param {string} state The new state, should be `inactive`, `active` or `finished`.
3219 */
3220
3221
3222 _createClass(InlineLoading, [{
3223 key: "setState",
3224 value: function setState(state) {
3225 var states = this.constructor.states;
3226 var values = Object.keys(states).map(function (key) {
3227 return states[key];
3228 });
3229
3230 if (values.indexOf(state) < 0) {
3231 throw new Error("One of the following value should be given as the state: ".concat(values.join(', ')));
3232 }
3233
3234 var elem = this.element;
3235 var _this$options = this.options,
3236 selectorSpinner = _this$options.selectorSpinner,
3237 selectorFinished = _this$options.selectorFinished,
3238 selectorTextActive = _this$options.selectorTextActive,
3239 selectorTextFinished = _this$options.selectorTextFinished;
3240 var spinner = elem.querySelector(selectorSpinner);
3241 var finished = elem.querySelector(selectorFinished);
3242 var textActive = elem.querySelector(selectorTextActive);
3243 var textFinished = elem.querySelector(selectorTextFinished);
3244
3245 if (spinner) {
3246 spinner.classList.toggle(this.options.classLoadingStop, state !== states.ACTIVE);
3247 toggleAttribute(spinner, 'hidden', state === states.FINISHED);
3248 }
3249
3250 if (finished) {
3251 toggleAttribute(finished, 'hidden', state !== states.FINISHED);
3252 }
3253
3254 if (textActive) {
3255 toggleAttribute(textActive, 'hidden', state !== states.ACTIVE);
3256 }
3257
3258 if (textFinished) {
3259 toggleAttribute(textFinished, 'hidden', state !== states.FINISHED);
3260 }
3261
3262 return this;
3263 }
3264 /**
3265 * The list of states.
3266 * @type {Object<string, string>}
3267 */
3268
3269 }], [{
3270 key: "options",
3271
3272 /**
3273 * The component options.
3274 * If `options` is specified in the constructor, {@linkcode InlineLoading.create .create()},
3275 * or {@linkcode InlineLoading.init .init()},
3276 * properties in this object are overriden for the instance being create and how {@linkcode InlineLoading.init .init()} works.
3277 * @member InlineLoading.options
3278 * @type {Object}
3279 * @property {string} selectorInit The CSS selector to find inline loading components.
3280 * @property {string} selectorSpinner The CSS selector to find the spinner.
3281 * @property {string} selectorFinished The CSS selector to find the "finished" icon.
3282 * @property {string} selectorTextActive The CSS selector to find the text describing the active state.
3283 * @property {string} selectorTextFinished The CSS selector to find the text describing the finished state.
3284 * @property {string} classLoadingStop The CSS class for spinner's stopped state.
3285 */
3286 get: function get() {
3287 var prefix = settings_1.prefix;
3288 return {
3289 selectorInit: '[data-inline-loading]',
3290 selectorSpinner: '[data-inline-loading-spinner]',
3291 selectorFinished: '[data-inline-loading-finished]',
3292 selectorTextActive: '[data-inline-loading-text-active]',
3293 selectorTextFinished: '[data-inline-loading-text-finished]',
3294 classLoadingStop: "".concat(prefix, "--loading--stop")
3295 };
3296 }
3297 }]);
3298
3299 return InlineLoading;
3300 }(mixin(createComponent, initComponentBySearch, handles));
3301
3302 _defineProperty(InlineLoading, "states",
3303 /* #__PURE_CLASS_PROPERTY__ */
3304 {
3305 INACTIVE: 'inactive',
3306 ACTIVE: 'active',
3307 FINISHED: 'finished'
3308 });
3309
3310 _defineProperty(InlineLoading, "components",
3311 /* #__PURE_CLASS_PROPERTY__ */
3312 new WeakMap());
3313
3314 var toArray$3 = function toArray(arrayLike) {
3315 return Array.prototype.slice.call(arrayLike);
3316 };
3317
3318 var Dropdown =
3319 /*#__PURE__*/
3320 function (_mixin) {
3321 _inherits(Dropdown, _mixin);
3322
3323 /**
3324 * A selector with drop downs.
3325 * @extends CreateComponent
3326 * @extends InitComponentBySearch
3327 * @extends TrackBlur
3328 * @param {HTMLElement} element The element working as a selector.
3329 * @param {Object} [options] The component options.
3330 * @param {string} [options.selectorItem] The CSS selector to find clickable areas in dropdown items.
3331 * @param {string} [options.selectorItemSelected] The CSS selector to find the clickable area in the selected dropdown item.
3332 * @param {string} [options.classSelected] The CSS class for the selected dropdown item.
3333 * @param {string} [options.classOpen] The CSS class for the open state.
3334 * @param {string} [options.classDisabled] The CSS class for the disabled state.
3335 * @param {string} [options.eventBeforeSelected]
3336 * The name of the custom event fired before a drop down item is selected.
3337 * Cancellation of this event stops selection of drop down item.
3338 * @param {string} [options.eventAfterSelected] The name of the custom event fired after a drop down item is selected.
3339 */
3340 function Dropdown(element, options) {
3341 var _this;
3342
3343 _classCallCheck(this, Dropdown);
3344
3345 _this = _possibleConstructorReturn(this, _getPrototypeOf(Dropdown).call(this, element, options));
3346
3347 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
3348 _this._toggle(event);
3349 }));
3350
3351 _this.manage(on(_this.element, 'keydown', function (event) {
3352 _this._handleKeyDown(event);
3353 }));
3354
3355 _this.manage(on(_this.element, 'click', function (event) {
3356 var item = eventMatches(event, _this.options.selectorItem);
3357
3358 if (item) {
3359 _this.select(item);
3360 }
3361 }));
3362
3363 return _this;
3364 }
3365 /**
3366 * Handles keydown event.
3367 * @param {Event} event The event triggering this method.
3368 */
3369
3370
3371 _createClass(Dropdown, [{
3372 key: "_handleKeyDown",
3373 value: function _handleKeyDown(event) {
3374 var isOpen = this.element.classList.contains(this.options.classOpen);
3375 var direction = {
3376 38: this.constructor.NAVIGATE.BACKWARD,
3377 40: this.constructor.NAVIGATE.FORWARD
3378 }[event.which];
3379
3380 if (isOpen && direction !== undefined) {
3381 this.navigate(direction);
3382 event.preventDefault(); // Prevents up/down keys from scrolling container
3383 } else {
3384 this._toggle(event);
3385 }
3386 }
3387 /**
3388 * Opens and closes the dropdown menu.
3389 * @param {Event} [event] The event triggering this method.
3390 */
3391
3392 }, {
3393 key: "_toggle",
3394 value: function _toggle(event) {
3395 var _this2 = this;
3396
3397 var isDisabled = this.element.classList.contains(this.options.classDisabled);
3398
3399 if (isDisabled) {
3400 return;
3401 }
3402
3403 if ([13, 32, 40].indexOf(event.which) >= 0 && !event.target.matches(this.options.selectorItem) || event.which === 27 || event.type === 'click') {
3404 var isOpen = this.element.classList.contains(this.options.classOpen);
3405 var isOfSelf = this.element.contains(event.target);
3406 var actions = {
3407 add: isOfSelf && event.which === 40 && !isOpen,
3408 remove: (!isOfSelf || event.which === 27) && isOpen,
3409 toggle: isOfSelf && event.which !== 27 && event.which !== 40
3410 };
3411 Object.keys(actions).forEach(function (action) {
3412 if (actions[action]) {
3413 _this2.element.classList[action](_this2.options.classOpen);
3414
3415 _this2.element.focus();
3416 }
3417 });
3418 var listItems = toArray$3(this.element.querySelectorAll(this.options.selectorItem));
3419 listItems.forEach(function (item) {
3420 if (_this2.element.classList.contains(_this2.options.classOpen)) {
3421 item.tabIndex = 0;
3422 } else {
3423 item.tabIndex = -1;
3424 }
3425 });
3426 }
3427 }
3428 /**
3429 * @returns {Element} Currently highlighted element.
3430 */
3431
3432 }, {
3433 key: "getCurrentNavigation",
3434 value: function getCurrentNavigation() {
3435 var focused = this.element.ownerDocument.activeElement;
3436 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(this.options.selectorItem) ? focused : null;
3437 }
3438 /**
3439 * Moves up/down the focus.
3440 * @param {number} direction The direction of navigating.
3441 */
3442
3443 }, {
3444 key: "navigate",
3445 value: function navigate(direction) {
3446 var items = toArray$3(this.element.querySelectorAll(this.options.selectorItem));
3447 var start = this.getCurrentNavigation() || this.element.querySelector(this.options.selectorItemSelected);
3448
3449 var getNextItem = function getNextItem(old) {
3450 var handleUnderflow = function handleUnderflow(i, l) {
3451 return i + (i >= 0 ? 0 : l);
3452 };
3453
3454 var handleOverflow = function handleOverflow(i, l) {
3455 return i - (i < l ? 0 : l);
3456 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
3457
3458
3459 var index = Math.max(items.indexOf(old) + direction, -1);
3460 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
3461 };
3462
3463 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
3464 if (!current.matches(this.options.selectorItemHidden) && !current.parentNode.matches(this.options.selectorItemHidden) && !current.matches(this.options.selectorItemSelected)) {
3465 current.focus();
3466 break;
3467 }
3468 }
3469 }
3470 /**
3471 * Handles clicking on the dropdown options, doing the following:
3472 * * Change Dropdown text to selected option.
3473 * * Remove selected option from options when selected.
3474 * * Emit custom events.
3475 * @param {HTMLElement} itemToSelect The element to be activated.
3476 */
3477
3478 }, {
3479 key: "select",
3480 value: function select(itemToSelect) {
3481 var _this3 = this;
3482
3483 var eventStart = new CustomEvent(this.options.eventBeforeSelected, {
3484 bubbles: true,
3485 cancelable: true,
3486 detail: {
3487 item: itemToSelect
3488 }
3489 });
3490
3491 if (this.element.dispatchEvent(eventStart)) {
3492 if (this.element.dataset.dropdownType !== 'navigation') {
3493 var selectorText = this.element.dataset.dropdownType !== 'inline' ? this.options.selectorText : this.options.selectorTextInner;
3494 var text = this.element.querySelector(selectorText);
3495
3496 if (text) {
3497 text.innerHTML = itemToSelect.innerHTML;
3498 }
3499
3500 itemToSelect.classList.add(this.options.classSelected);
3501 }
3502
3503 this.element.dataset.value = itemToSelect.parentElement.dataset.value;
3504 toArray$3(this.element.querySelectorAll(this.options.selectorItemSelected)).forEach(function (item) {
3505 if (itemToSelect !== item) {
3506 item.classList.remove(_this3.options.classSelected);
3507 }
3508 });
3509 this.element.dispatchEvent(new CustomEvent(this.options.eventAfterSelected, {
3510 bubbles: true,
3511 cancelable: true,
3512 detail: {
3513 item: itemToSelect
3514 }
3515 }));
3516 }
3517 }
3518 /**
3519 * Closes the dropdown menu if this component loses focus.
3520 */
3521
3522 }, {
3523 key: "handleBlur",
3524 value: function handleBlur() {
3525 this.element.classList.remove(this.options.classOpen);
3526 }
3527 /**
3528 * The map associating DOM element and selector instance.
3529 * @member Dropdown.components
3530 * @type {WeakMap}
3531 */
3532
3533 }], [{
3534 key: "options",
3535
3536 /**
3537 * The component options.
3538 * If `options` is specified in the constructor, {@linkcode Dropdown.create .create()}, or {@linkcode Dropdown.init .init()},
3539 * properties in this object are overriden for the instance being create and how {@linkcode Dropdown.init .init()} works.
3540 * @member Dropdown.options
3541 * @type {Object}
3542 * @property {string} selectorInit The CSS selector to find selectors.
3543 * @property {string} [selectorText] The CSS selector to find the element showing the selected item.
3544 * @property {string} [selectorTextInner] The CSS selector to find the element showing the selected item, used for inline mode.
3545 * @property {string} [selectorItem] The CSS selector to find clickable areas in dropdown items.
3546 * @property {string} [selectorItemHidden]
3547 * The CSS selector to find hidden dropdown items.
3548 * Used to skip dropdown items for keyboard navigation.
3549 * @property {string} [selectorItemSelected] The CSS selector to find the clickable area in the selected dropdown item.
3550 * @property {string} [classSelected] The CSS class for the selected dropdown item.
3551 * @property {string} [classOpen] The CSS class for the open state.
3552 * @property {string} [classDisabled] The CSS class for the disabled state.
3553 * @property {string} [eventBeforeSelected]
3554 * The name of the custom event fired before a drop down item is selected.
3555 * Cancellation of this event stops selection of drop down item.
3556 * @property {string} [eventAfterSelected] The name of the custom event fired after a drop down item is selected.
3557 */
3558 get: function get() {
3559 var prefix = settings_1.prefix;
3560 return {
3561 selectorInit: '[data-dropdown]',
3562 selectorText: ".".concat(prefix, "--dropdown-text"),
3563 selectorTextInner: ".".concat(prefix, "--dropdown-text__inner"),
3564 selectorItem: ".".concat(prefix, "--dropdown-link"),
3565 selectorItemSelected: ".".concat(prefix, "--dropdown--selected"),
3566 selectorItemHidden: "[hidden],[aria-hidden=\"true\"]",
3567 classSelected: "".concat(prefix, "--dropdown--selected"),
3568 classOpen: "".concat(prefix, "--dropdown--open"),
3569 classDisabled: "".concat(prefix, "--dropdown--disabled"),
3570 eventBeforeSelected: 'dropdown-beingselected',
3571 eventAfterSelected: 'dropdown-selected'
3572 };
3573 }
3574 /**
3575 * Enum for navigating backward/forward.
3576 * @readonly
3577 * @member Dropdown.NAVIGATE
3578 * @type {Object}
3579 * @property {number} BACKWARD Navigating backward.
3580 * @property {number} FORWARD Navigating forward.
3581 */
3582
3583 }]);
3584
3585 return Dropdown;
3586 }(mixin(createComponent, initComponentBySearch, exports$2));
3587
3588 _defineProperty(Dropdown, "components",
3589 /* #__PURE_CLASS_PROPERTY__ */
3590 new WeakMap());
3591
3592 _defineProperty(Dropdown, "NAVIGATE",
3593 /* #__PURE_CLASS_PROPERTY__ */
3594 {
3595 BACKWARD: -1,
3596 FORWARD: 1
3597 });
3598
3599 var NumberInput =
3600 /*#__PURE__*/
3601 function (_mixin) {
3602 _inherits(NumberInput, _mixin);
3603
3604 /**
3605 * Number input UI.
3606 * @extends CreateComponent
3607 * @extends InitComponentBySearch
3608 * @extends Handles
3609 * @param {HTMLElement} element The element working as a number input UI.
3610 */
3611 function NumberInput(element, options) {
3612 var _this;
3613
3614 _classCallCheck(this, NumberInput);
3615
3616 _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.
3617 // <svg> does not have `Element.classList` in IE11
3618
3619 _this.manage(on(_this.element.querySelector('.up-icon'), 'click', function (event) {
3620 _this._handleClick(event);
3621 }));
3622
3623 _this.manage(on(_this.element.querySelector('.down-icon'), 'click', function (event) {
3624 _this._handleClick(event);
3625 }));
3626
3627 return _this;
3628 }
3629 /**
3630 * Increase/decrease number by clicking on up/down icons.
3631 * @param {Event} event The event triggering this method.
3632 */
3633
3634
3635 _createClass(NumberInput, [{
3636 key: "_handleClick",
3637 value: function _handleClick(event) {
3638 var numberInput = this.element.querySelector(this.options.selectorInput);
3639 var target = event.currentTarget.getAttribute('class').split(' ');
3640
3641 if (target.indexOf('up-icon') >= 0) {
3642 ++numberInput.value;
3643 } else if (target.indexOf('down-icon') >= 0) {
3644 --numberInput.value;
3645 } // Programmatic change in value (including `stepUp()`/`stepDown()`) won't fire change event
3646
3647
3648 numberInput.dispatchEvent(new CustomEvent('change', {
3649 bubbles: true,
3650 cancelable: false
3651 }));
3652 }
3653 /**
3654 * The map associating DOM element and number input UI instance.
3655 * @member NumberInput.components
3656 * @type {WeakMap}
3657 */
3658
3659 }], [{
3660 key: "options",
3661
3662 /**
3663 * The component options.
3664 * If `options` is specified in the constructor,
3665 * {@linkcode NumberInput.create .create()}, or {@linkcode NumberInput.init .init()},
3666 * properties in this object are overriden for the instance being create and how {@linkcode NumberInput.init .init()} works.
3667 * @member NumberInput.options
3668 * @type {Object}
3669 * @property {string} selectorInit The CSS selector to find number input UIs.
3670 * @property {string} [selectorInput] The CSS selector to find the `<input>` element.
3671 */
3672 get: function get() {
3673 var prefix = settings_1.prefix;
3674 return {
3675 selectorInit: '[data-numberinput]',
3676 selectorInput: ".".concat(prefix, "--number input")
3677 };
3678 }
3679 }]);
3680
3681 return NumberInput;
3682 }(mixin(createComponent, initComponentBySearch, handles));
3683
3684 _defineProperty(NumberInput, "components",
3685 /* #__PURE_CLASS_PROPERTY__ */
3686 new WeakMap());
3687
3688 var toArray$4 = function toArray(arrayLike) {
3689 return Array.prototype.slice.call(arrayLike);
3690 };
3691
3692 var DataTable =
3693 /*#__PURE__*/
3694 function (_mixin) {
3695 _inherits(DataTable, _mixin);
3696
3697 /**
3698 * Data Table
3699 * @extends CreateComponent
3700 * @extends InitComponentBySearch
3701 * @extends EventedState
3702 * @extends Handles
3703 * @param {HTMLElement} element The root element of tables
3704 * @param {Object} [options] the... options
3705 * @param {string} [options.selectorInit] selector initialization
3706 * @param {string} [options.selectorExpandCells] css selector for expand
3707 * @param {string} [options.expandableRow] css selector for expand
3708 * @param {string} [options.selectorParentRows] css selector for rows housing expansion
3709 * @param {string} [options.selectorTableBody] root css for table body
3710 * @param {string} [options.eventTrigger] selector for event bubble capture points
3711 * @param {string} [options.eventParentContainer] used find the bubble container
3712 */
3713 function DataTable(_element, options) {
3714 var _this;
3715
3716 _classCallCheck(this, DataTable);
3717
3718 _this = _possibleConstructorReturn(this, _getPrototypeOf(DataTable).call(this, _element, options));
3719
3720 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleState", function (element, evt) {
3721 var data = element.dataset;
3722 var label = data.label ? data.label : '';
3723 var previousValue = data.previousValue ? data.previousValue : '';
3724 var initialEvt = evt;
3725
3726 _this.changeState({
3727 group: data.event,
3728 element: element,
3729 label: label,
3730 previousValue: previousValue,
3731 initialEvt: initialEvt
3732 });
3733 });
3734
3735 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_zebraStripe", function (parentRows) {
3736 parentRows.forEach(function (item, index) {
3737 if (index % 2 === 0) {
3738 item.classList.add(_this.options.classParentRowEven);
3739
3740 if (item.nextElementSibling && item.nextElementSibling.classList.contains(_this.options.classExpandableRow)) {
3741 item.nextElementSibling.classList.add(_this.options.classExpandableRowEven);
3742 }
3743 } else {
3744 item.classList.remove(_this.options.classParentRowEven);
3745 }
3746 });
3747 });
3748
3749 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_initExpandableRows", function (expandableRows) {
3750 expandableRows.forEach(function (item) {
3751 item.classList.remove(_this.options.classExpandableRowHidden);
3752
3753 _this.tableBody.removeChild(item);
3754 });
3755 });
3756
3757 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleRowExpand", function (_ref) {
3758 var element = _ref.element,
3759 initialEvt = _ref.initialEvt;
3760 var parent = eventMatches(initialEvt, _this.options.eventParentContainer);
3761
3762 var index = _this.expandCells.indexOf(element);
3763
3764 if (element.dataset.previousValue === undefined || element.dataset.previousValue === 'expanded') {
3765 element.dataset.previousValue = 'collapsed';
3766
3767 _this.tableBody.insertBefore(_this.expandableRows[index], _this.parentRows[index + 1]);
3768 } else {
3769 _this.tableBody.removeChild(parent.nextElementSibling);
3770
3771 element.dataset.previousValue = 'expanded';
3772 }
3773 });
3774
3775 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleSort", function (detail) {
3776 var element = detail.element,
3777 previousValue = detail.previousValue;
3778
3779 if (!previousValue || previousValue === 'descending') {
3780 element.dataset.previousValue = 'ascending';
3781 element.classList.add(_this.options.classTableSortAscending);
3782 } else {
3783 element.dataset.previousValue = 'descending';
3784 element.classList.remove(_this.options.classTableSortAscending);
3785 }
3786 });
3787
3788 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleSelectAll", function (detail) {
3789 var element = detail.element,
3790 previousValue = detail.previousValue;
3791 var inputs = toArray$4(_this.element.querySelectorAll(_this.options.selectorCheckbox));
3792
3793 if (!previousValue || previousValue === 'toggled') {
3794 inputs.forEach(function (item) {
3795 item.checked = true; // eslint-disable-line no-param-reassign
3796 });
3797 element.dataset.previousValue = 'off';
3798 } else {
3799 inputs.forEach(function (item) {
3800 item.checked = false; // eslint-disable-line no-param-reassign
3801 });
3802 element.dataset.previousValue = 'toggled';
3803 }
3804 });
3805
3806 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "refreshRows", function () {
3807 var newExpandCells = toArray$4(_this.element.querySelectorAll(_this.options.selectorExpandCells));
3808 var newExpandableRows = toArray$4(_this.element.querySelectorAll(_this.options.selectorExpandableRows));
3809 var newParentRows = toArray$4(_this.element.querySelectorAll(_this.options.selectorParentRows)); // check if this is a refresh or the first time
3810
3811 if (_this.parentRows.length > 0) {
3812 var diffParentRows = newParentRows.filter(function (newRow) {
3813 return !_this.parentRows.some(function (oldRow) {
3814 return oldRow === newRow;
3815 });
3816 }); // check if there are expandable rows
3817
3818 if (newExpandableRows.length > 0) {
3819 var diffExpandableRows = diffParentRows.map(function (newRow) {
3820 return newRow.nextElementSibling;
3821 });
3822 var mergedExpandableRows = toArray$4.apply(void 0, [_this.expandableRows].concat(_toConsumableArray(diffExpandableRows)));
3823
3824 _this._initExpandableRows(diffExpandableRows);
3825
3826 _this.expandableRows = mergedExpandableRows;
3827 }
3828
3829 _this._zebraStripe(newParentRows);
3830 } else {
3831 _this._zebraStripe(newParentRows);
3832
3833 if (newExpandableRows.length > 0) {
3834 _this._initExpandableRows(newExpandableRows);
3835
3836 _this.expandableRows = newExpandableRows;
3837 }
3838 }
3839
3840 _this.expandCells = newExpandCells;
3841 _this.parentRows = newParentRows;
3842 });
3843
3844 _this.container = _element.parentNode; // requires the immediate parent to be the container
3845
3846 _this.tableBody = _this.element.querySelector(_this.options.selectorTableBody);
3847 _this.expandCells = [];
3848 _this.expandableRows = [];
3849 _this.parentRows = [];
3850 _this.overflowInitialized = false;
3851
3852 _this.refreshRows();
3853
3854 _this.manage(on(_this.element, 'click', function (evt) {
3855 var eventElement = eventMatches(evt, _this.options.eventTrigger);
3856
3857 if (eventElement) {
3858 _this._toggleState(eventElement, evt);
3859 }
3860 }));
3861
3862 _this.manage(on(_this.element, 'keydown', function (evt) {
3863 if (evt.which === 13) {
3864 var eventElement = eventMatches(evt, _this.options.eventTrigger);
3865
3866 if (eventElement) {
3867 _this._toggleState(eventElement, evt);
3868 }
3869 }
3870 }));
3871
3872 return _this;
3873 }
3874 /**
3875 * Toggles the given state.
3876 * @private
3877 * @param {Object} detail The detail of the event trigging this action.
3878 * @param {Function} callback Callback called when change in state completes.
3879 */
3880
3881
3882 _createClass(DataTable, [{
3883 key: "_changeState",
3884 value: function _changeState(detail, callback) {
3885 this[this.constructor.eventHandlers[detail.group]](detail);
3886 callback();
3887 }
3888 /**
3889 * Toggles the state of this component specified by `data-event` attribute of the given element.
3890 * @param {HTMLElement} element The element.
3891 * @param {Event} evt The event trigging this action.
3892 */
3893
3894 }], [{
3895 key: "options",
3896 get: function get() {
3897 var prefix = settings_1.prefix;
3898 return {
3899 selectorInit: '[data-responsive-table]',
3900 selectorExpandCells: ".".concat(prefix, "--table-expand"),
3901 selectorExpandableRows: ".".concat(prefix, "--expandable-row"),
3902 selectorParentRows: ".".concat(prefix, "--parent-row"),
3903 selectorTableBody: ".".concat(prefix, "--table-body"),
3904 selectorCheckbox: ".".concat(prefix, "--checkbox"),
3905 classParentRowEven: "".concat(prefix, "--parent-row--even"),
3906 classExpandableRow: "".concat(prefix, "--expandable-row"),
3907 classExpandableRowEven: "".concat(prefix, "--expandable-row--even"),
3908 classExpandableRowHidden: "".concat(prefix, "--expandable-row--hidden"),
3909 classTableSortAscending: "".concat(prefix, "--table-sort--ascending"),
3910 eventBeforeExpand: 'responsive-table-beforetoggleexpand',
3911 eventAfterExpand: 'responsive-table-aftertoggleexpand',
3912 eventBeforeSort: 'responsive-table-beforetogglesort',
3913 eventAfterSort: 'responsive-table-aftertogglesort',
3914 eventBeforeSelectAll: 'responsive-table-beforetoggleselectall',
3915 eventAfterSelectAll: 'responsive-table-aftertoggleselectall',
3916 eventTrigger: '[data-event]',
3917 eventParentContainer: '[data-parent-row]'
3918 };
3919 }
3920 }]);
3921
3922 return DataTable;
3923 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
3924
3925 _defineProperty(DataTable, "components",
3926 /* #__PURE_CLASS_PROPERTY__ */
3927 new WeakMap());
3928
3929 _defineProperty(DataTable, "eventHandlers",
3930 /* #__PURE_CLASS_PROPERTY__ */
3931 {
3932 expand: '_toggleRowExpand',
3933 sort: '_toggleSort',
3934 'select-all': '_toggleSelectAll'
3935 });
3936
3937 var dataTable = !breakingChangesX ? DataTable : removedComponent('DataTable');
3938
3939 var toArray$5 = function toArray(arrayLike) {
3940 return Array.prototype.slice.call(arrayLike);
3941 };
3942
3943 var DataTableV2 =
3944 /*#__PURE__*/
3945 function (_mixin) {
3946 _inherits(DataTableV2, _mixin);
3947
3948 /**
3949 * Data Table
3950 * @extends CreateComponent
3951 * @extends InitComponentBySearch
3952 * @extends EventedState
3953 * @param {HTMLElement} element The root element of tables
3954 * @param {Object} [options] the... options
3955 * @param {string} [options.selectorInit] selector initialization
3956 * @param {string} [options.selectorExpandCells] css selector for expand
3957 * @param {string} [options.expandableRow] css selector for expand
3958 * @param {string} [options.selectorParentRows] css selector for rows housing expansion
3959 * @param {string} [options.selectorTableBody] root css for table body
3960 * @param {string} [options.eventTrigger] selector for event bubble capture points
3961 * @param {string} [options.eventParentContainer] used find the bubble container
3962 */
3963 function DataTableV2(_element, options) {
3964 var _this;
3965
3966 _classCallCheck(this, DataTableV2);
3967
3968 _this = _possibleConstructorReturn(this, _getPrototypeOf(DataTableV2).call(this, _element, options));
3969
3970 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_sortToggle", function (detail) {
3971 var element = detail.element,
3972 previousValue = detail.previousValue;
3973 toArray$5(_this.tableHeaders).forEach(function (header) {
3974 var sortEl = header.querySelector(_this.options.selectorTableSort);
3975
3976 if (sortEl !== null && sortEl !== element) {
3977 sortEl.classList.remove(_this.options.classTableSortActive);
3978 sortEl.classList.remove(_this.options.classTableSortAscending);
3979 }
3980 });
3981
3982 if (!previousValue) {
3983 element.dataset.previousValue = 'ascending';
3984 element.classList.add(_this.options.classTableSortActive);
3985 element.classList.add(_this.options.classTableSortAscending);
3986 } else if (previousValue === 'ascending') {
3987 element.dataset.previousValue = 'descending';
3988 element.classList.add(_this.options.classTableSortActive);
3989 element.classList.remove(_this.options.classTableSortAscending);
3990 } else if (previousValue === 'descending') {
3991 element.removeAttribute('data-previous-value');
3992 element.classList.remove(_this.options.classTableSortActive);
3993 element.classList.remove(_this.options.classTableSortAscending);
3994 }
3995 });
3996
3997 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_selectToggle", function (detail) {
3998 var element = detail.element;
3999 var checked = element.checked; // increment the count
4000
4001 _this.state.checkboxCount += checked ? 1 : -1;
4002 _this.countEl.textContent = _this.state.checkboxCount;
4003 var row = element.parentNode.parentNode;
4004 row.classList.toggle(_this.options.classTableSelected); // toggle on/off batch action bar
4005
4006 _this._actionBarToggle(_this.state.checkboxCount > 0);
4007 });
4008
4009 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_selectAllToggle", function (_ref) {
4010 var element = _ref.element;
4011 var checked = element.checked;
4012 var inputs = toArray$5(_this.element.querySelectorAll(_this.options.selectorCheckbox));
4013 _this.state.checkboxCount = checked ? inputs.length - 1 : 0;
4014 inputs.forEach(function (item) {
4015 item.checked = checked;
4016 var row = item.parentNode.parentNode;
4017
4018 if (checked && row) {
4019 row.classList.add(_this.options.classTableSelected);
4020 } else {
4021 row.classList.remove(_this.options.classTableSelected);
4022 }
4023 });
4024
4025 _this._actionBarToggle(_this.state.checkboxCount > 0);
4026
4027 if (_this.batchActionEl) {
4028 _this.countEl.textContent = _this.state.checkboxCount;
4029 }
4030 });
4031
4032 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_actionBarCancel", function () {
4033 var inputs = toArray$5(_this.element.querySelectorAll(_this.options.selectorCheckbox));
4034 var row = toArray$5(_this.element.querySelectorAll(_this.options.selectorTableSelected));
4035 row.forEach(function (item) {
4036 item.classList.remove(_this.options.classTableSelected);
4037 });
4038 inputs.forEach(function (item) {
4039 item.checked = false;
4040 });
4041 _this.state.checkboxCount = 0;
4042
4043 _this._actionBarToggle(false);
4044
4045 if (_this.batchActionEl) {
4046 _this.countEl.textContent = _this.state.checkboxCount;
4047 }
4048 });
4049
4050 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_actionBarToggle", function (toggleOn) {
4051 var transition = function transition(evt) {
4052 _this.batchActionEl.removeEventListener('transitionend', transition);
4053
4054 if (evt.target.matches(_this.options.selectorActions)) {
4055 if (_this.batchActionEl.dataset.active === 'false') {
4056 _this.batchActionEl.setAttribute('tabIndex', -1);
4057 } else {
4058 _this.batchActionEl.setAttribute('tabIndex', 0);
4059 }
4060 }
4061 };
4062
4063 if (toggleOn) {
4064 _this.batchActionEl.dataset.active = true;
4065
4066 _this.batchActionEl.classList.add(_this.options.classActionBarActive);
4067 } else if (_this.batchActionEl) {
4068 _this.batchActionEl.dataset.active = false;
4069
4070 _this.batchActionEl.classList.remove(_this.options.classActionBarActive);
4071 }
4072
4073 if (_this.batchActionEl) {
4074 _this.batchActionEl.addEventListener('transitionend', transition);
4075 }
4076 });
4077
4078 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_expandableRowsInit", function (expandableRows) {
4079 expandableRows.forEach(function (item) {
4080 item.classList.remove(_this.options.classExpandableRowHidden);
4081
4082 _this.tableBody.removeChild(item);
4083 });
4084 });
4085
4086 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_rowExpandToggle", function (_ref2) {
4087 var element = _ref2.element,
4088 initialEvt = _ref2.initialEvt;
4089 var parent = eventMatches(initialEvt, _this.options.eventParentContainer);
4090
4091 var index = _this.expandCells.indexOf(element);
4092
4093 if (element.dataset.previousValue === undefined || element.dataset.previousValue === 'expanded') {
4094 element.dataset.previousValue = 'collapsed';
4095 parent.classList.add(_this.options.classExpandableRow);
4096
4097 _this.tableBody.insertBefore(_this.expandableRows[index], _this.parentRows[index + 1]);
4098 } else {
4099 parent.classList.remove(_this.options.classExpandableRow);
4100
4101 _this.tableBody.removeChild(parent.nextElementSibling);
4102
4103 element.dataset.previousValue = 'expanded';
4104 }
4105 });
4106
4107 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_expandableHoverToggle", function (element) {
4108 element.previousElementSibling.classList.add(_this.options.classExpandableRowHover);
4109
4110 var mouseout = function mouseout() {
4111 element.previousElementSibling.classList.remove(_this.options.classExpandableRowHover);
4112 element.removeEventListener('mouseout', mouseout);
4113 };
4114
4115 element.addEventListener('mouseout', mouseout);
4116 });
4117
4118 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggleState", function (element, evt) {
4119 var data = element.dataset;
4120 var label = data.label ? data.label : '';
4121 var previousValue = data.previousValue ? data.previousValue : '';
4122 var initialEvt = evt;
4123
4124 _this.changeState({
4125 group: data.event,
4126 element: element,
4127 label: label,
4128 previousValue: previousValue,
4129 initialEvt: initialEvt
4130 });
4131 });
4132
4133 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_keydownHandler", function (evt) {
4134 if (evt.which === 27) {
4135 _this._actionBarCancel();
4136 }
4137 });
4138
4139 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "refreshRows", function () {
4140 var newExpandCells = toArray$5(_this.element.querySelectorAll(_this.options.selectorExpandCells));
4141 var newExpandableRows = toArray$5(_this.element.querySelectorAll(_this.options.selectorExpandableRows));
4142 var newParentRows = toArray$5(_this.element.querySelectorAll(_this.options.selectorParentRows)); // check if this is a refresh or the first time
4143
4144 if (_this.parentRows.length > 0) {
4145 var diffParentRows = newParentRows.filter(function (newRow) {
4146 return !_this.parentRows.some(function (oldRow) {
4147 return oldRow === newRow;
4148 });
4149 }); // check if there are expandable rows
4150
4151 if (newExpandableRows.length > 0) {
4152 var diffExpandableRows = diffParentRows.map(function (newRow) {
4153 return newRow.nextElementSibling;
4154 });
4155 var mergedExpandableRows = [].concat(_toConsumableArray(toArray$5(_this.expandableRows)), _toConsumableArray(toArray$5(diffExpandableRows)));
4156
4157 _this._expandableRowsInit(diffExpandableRows);
4158
4159 _this.expandableRows = mergedExpandableRows;
4160 }
4161 } else if (newExpandableRows.length > 0) {
4162 _this._expandableRowsInit(newExpandableRows);
4163
4164 _this.expandableRows = newExpandableRows;
4165 }
4166
4167 _this.expandCells = newExpandCells;
4168 _this.parentRows = newParentRows;
4169 });
4170
4171 _this.container = _element.parentNode;
4172 _this.toolbarEl = _this.element.querySelector(_this.options.selectorToolbar);
4173 _this.batchActionEl = _this.element.querySelector(_this.options.selectorActions);
4174 _this.countEl = _this.element.querySelector(_this.options.selectorCount);
4175 _this.cancelEl = _this.element.querySelector(_this.options.selectorActionCancel);
4176 _this.tableHeaders = _this.element.querySelectorAll('th');
4177 _this.tableBody = _this.element.querySelector(_this.options.selectorTableBody);
4178 _this.expandCells = [];
4179 _this.expandableRows = [];
4180 _this.parentRows = [];
4181
4182 _this.refreshRows();
4183
4184 _this.element.addEventListener('mouseover', function (evt) {
4185 var eventElement = eventMatches(evt, _this.options.selectorChildRow);
4186
4187 if (eventElement) {
4188 _this._expandableHoverToggle(eventElement, true);
4189 }
4190 });
4191
4192 _this.element.addEventListener('click', function (evt) {
4193 var eventElement = eventMatches(evt, _this.options.eventTrigger);
4194
4195 if (eventElement) {
4196 _this._toggleState(eventElement, evt);
4197 }
4198 });
4199
4200 _this.element.addEventListener('keydown', _this._keydownHandler);
4201
4202 _this.state = {
4203 checkboxCount: 0
4204 };
4205 return _this;
4206 }
4207
4208 _createClass(DataTableV2, [{
4209 key: "_changeState",
4210 value: function _changeState(detail, callback) {
4211 this[this.constructor.eventHandlers[detail.group]](detail);
4212 callback();
4213 }
4214 }], [{
4215 key: "options",
4216 get: function get() {
4217 var prefix = settings_1.prefix;
4218 return {
4219 selectorInit: '[data-table-v2]',
4220 selectorToolbar: ".".concat(prefix, "--table--toolbar"),
4221 selectorActions: ".".concat(prefix, "--batch-actions"),
4222 selectorCount: '[data-items-selected]',
4223 selectorActionCancel: ".".concat(prefix, "--batch-summary__cancel"),
4224 selectorCheckbox: ".".concat(prefix, "--checkbox"),
4225 selectorExpandCells: ".".concat(prefix, "--table-expand-v2"),
4226 selectorExpandableRows: ".".concat(prefix, "--expandable-row-v2"),
4227 selectorParentRows: ".".concat(prefix, "--parent-row-v2"),
4228 selectorChildRow: '[data-child-row]',
4229 selectorTableBody: 'tbody',
4230 selectorTableSort: ".".concat(prefix, "--table-sort-v2"),
4231 selectorTableSelected: ".".concat(prefix, "--data-table-v2--selected"),
4232 classExpandableRow: "".concat(prefix, "--expandable-row-v2"),
4233 classExpandableRowHidden: "".concat(prefix, "--expandable-row--hidden-v2"),
4234 classExpandableRowHover: "".concat(prefix, "--expandable-row--hover-v2"),
4235 classTableSortAscending: "".concat(prefix, "--table-sort-v2--ascending"),
4236 classTableSortActive: "".concat(prefix, "--table-sort-v2--active"),
4237 classActionBarActive: "".concat(prefix, "--batch-actions--active"),
4238 classTableSelected: "".concat(prefix, "--data-table-v2--selected"),
4239 eventBeforeExpand: 'data-table-v2-beforetoggleexpand',
4240 eventAfterExpand: 'data-table-v2-aftertoggleexpand',
4241 eventBeforeSort: 'data-table-v2-beforetogglesort',
4242 eventAfterSort: 'data-table-v2-aftertogglesort',
4243 eventTrigger: '[data-event]',
4244 eventParentContainer: '[data-parent-row]'
4245 };
4246 }
4247 }]);
4248
4249 return DataTableV2;
4250 }(mixin(createComponent, initComponentBySearch, eventedState));
4251
4252 _defineProperty(DataTableV2, "components",
4253 /* #__PURE_CLASS_PROPERTY__ */
4254 new WeakMap());
4255
4256 _defineProperty(DataTableV2, "eventHandlers",
4257 /* #__PURE_CLASS_PROPERTY__ */
4258 {
4259 expand: '_rowExpandToggle',
4260 sort: '_sortToggle',
4261 select: '_selectToggle',
4262 'select-all': '_selectAllToggle',
4263 'action-bar-cancel': '_actionBarCancel'
4264 });
4265
4266 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
4267
4268 function createCommonjsModule(fn, module) {
4269 return module = { exports: {} }, fn(module, module.exports), module.exports;
4270 }
4271
4272 var flatpickr = createCommonjsModule(function (module, exports) {
4273 /* flatpickr v4.5.7, @license MIT */
4274 (function (global, factory) {
4275 module.exports = factory();
4276 }(commonjsGlobal, function () {
4277 /*! *****************************************************************************
4278 Copyright (c) Microsoft Corporation. All rights reserved.
4279 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4280 this file except in compliance with the License. You may obtain a copy of the
4281 License at http://www.apache.org/licenses/LICENSE-2.0
4282
4283 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
4284 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
4285 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
4286 MERCHANTABLITY OR NON-INFRINGEMENT.
4287
4288 See the Apache Version 2.0 License for specific language governing permissions
4289 and limitations under the License.
4290 ***************************************************************************** */
4291
4292 var __assign = function() {
4293 __assign = Object.assign || function __assign(t) {
4294 for (var s, i = 1, n = arguments.length; i < n; i++) {
4295 s = arguments[i];
4296 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
4297 }
4298 return t;
4299 };
4300 return __assign.apply(this, arguments);
4301 };
4302
4303 var HOOKS = [
4304 "onChange",
4305 "onClose",
4306 "onDayCreate",
4307 "onDestroy",
4308 "onKeyDown",
4309 "onMonthChange",
4310 "onOpen",
4311 "onParseConfig",
4312 "onReady",
4313 "onValueUpdate",
4314 "onYearChange",
4315 "onPreCalendarPosition",
4316 ];
4317 var defaults = {
4318 _disable: [],
4319 _enable: [],
4320 allowInput: false,
4321 altFormat: "F j, Y",
4322 altInput: false,
4323 altInputClass: "form-control input",
4324 animate: typeof window === "object" &&
4325 window.navigator.userAgent.indexOf("MSIE") === -1,
4326 ariaDateFormat: "F j, Y",
4327 clickOpens: true,
4328 closeOnSelect: true,
4329 conjunction: ", ",
4330 dateFormat: "Y-m-d",
4331 defaultHour: 12,
4332 defaultMinute: 0,
4333 defaultSeconds: 0,
4334 disable: [],
4335 disableMobile: false,
4336 enable: [],
4337 enableSeconds: false,
4338 enableTime: false,
4339 errorHandler: function (err) {
4340 return typeof console !== "undefined" && console.warn(err);
4341 },
4342 getWeek: function (givenDate) {
4343 var date = new Date(givenDate.getTime());
4344 date.setHours(0, 0, 0, 0);
4345 // Thursday in current week decides the year.
4346 date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
4347 // January 4 is always in week 1.
4348 var week1 = new Date(date.getFullYear(), 0, 4);
4349 // Adjust to Thursday in week 1 and count number of weeks from date to week1.
4350 return (1 +
4351 Math.round(((date.getTime() - week1.getTime()) / 86400000 -
4352 3 +
4353 ((week1.getDay() + 6) % 7)) /
4354 7));
4355 },
4356 hourIncrement: 1,
4357 ignoredFocusElements: [],
4358 inline: false,
4359 locale: "default",
4360 minuteIncrement: 5,
4361 mode: "single",
4362 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>",
4363 noCalendar: false,
4364 now: new Date(),
4365 onChange: [],
4366 onClose: [],
4367 onDayCreate: [],
4368 onDestroy: [],
4369 onKeyDown: [],
4370 onMonthChange: [],
4371 onOpen: [],
4372 onParseConfig: [],
4373 onReady: [],
4374 onValueUpdate: [],
4375 onYearChange: [],
4376 onPreCalendarPosition: [],
4377 plugins: [],
4378 position: "auto",
4379 positionElement: undefined,
4380 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>",
4381 shorthandCurrentMonth: false,
4382 showMonths: 1,
4383 static: false,
4384 time_24hr: false,
4385 weekNumbers: false,
4386 wrap: false
4387 };
4388
4389 var english = {
4390 weekdays: {
4391 shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
4392 longhand: [
4393 "Sunday",
4394 "Monday",
4395 "Tuesday",
4396 "Wednesday",
4397 "Thursday",
4398 "Friday",
4399 "Saturday",
4400 ]
4401 },
4402 months: {
4403 shorthand: [
4404 "Jan",
4405 "Feb",
4406 "Mar",
4407 "Apr",
4408 "May",
4409 "Jun",
4410 "Jul",
4411 "Aug",
4412 "Sep",
4413 "Oct",
4414 "Nov",
4415 "Dec",
4416 ],
4417 longhand: [
4418 "January",
4419 "February",
4420 "March",
4421 "April",
4422 "May",
4423 "June",
4424 "July",
4425 "August",
4426 "September",
4427 "October",
4428 "November",
4429 "December",
4430 ]
4431 },
4432 daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
4433 firstDayOfWeek: 0,
4434 ordinal: function (nth) {
4435 var s = nth % 100;
4436 if (s > 3 && s < 21)
4437 return "th";
4438 switch (s % 10) {
4439 case 1:
4440 return "st";
4441 case 2:
4442 return "nd";
4443 case 3:
4444 return "rd";
4445 default:
4446 return "th";
4447 }
4448 },
4449 rangeSeparator: " to ",
4450 weekAbbreviation: "Wk",
4451 scrollTitle: "Scroll to increment",
4452 toggleTitle: "Click to toggle",
4453 amPM: ["AM", "PM"],
4454 yearAriaLabel: "Year"
4455 };
4456
4457 var pad = function (number) { return ("0" + number).slice(-2); };
4458 var int = function (bool) { return (bool === true ? 1 : 0); };
4459 /* istanbul ignore next */
4460 function debounce(func, wait, immediate) {
4461 if (immediate === void 0) { immediate = false; }
4462 var timeout;
4463 return function () {
4464 var context = this, args = arguments;
4465 timeout !== null && clearTimeout(timeout);
4466 timeout = window.setTimeout(function () {
4467 timeout = null;
4468 if (!immediate)
4469 func.apply(context, args);
4470 }, wait);
4471 if (immediate && !timeout)
4472 func.apply(context, args);
4473 };
4474 }
4475 var arrayify = function (obj) {
4476 return obj instanceof Array ? obj : [obj];
4477 };
4478
4479 function toggleClass(elem, className, bool) {
4480 if (bool === true)
4481 return elem.classList.add(className);
4482 elem.classList.remove(className);
4483 }
4484 function createElement(tag, className, content) {
4485 var e = window.document.createElement(tag);
4486 className = className || "";
4487 content = content || "";
4488 e.className = className;
4489 if (content !== undefined)
4490 e.textContent = content;
4491 return e;
4492 }
4493 function clearNode(node) {
4494 while (node.firstChild)
4495 node.removeChild(node.firstChild);
4496 }
4497 function findParent(node, condition) {
4498 if (condition(node))
4499 return node;
4500 else if (node.parentNode)
4501 return findParent(node.parentNode, condition);
4502 return undefined; // nothing found
4503 }
4504 function createNumberInput(inputClassName, opts) {
4505 var wrapper = createElement("div", "numInputWrapper"), numInput = createElement("input", "numInput " + inputClassName), arrowUp = createElement("span", "arrowUp"), arrowDown = createElement("span", "arrowDown");
4506 if (navigator.userAgent.indexOf("MSIE 9.0") === -1) {
4507 numInput.type = "number";
4508 }
4509 else {
4510 numInput.type = "text";
4511 numInput.pattern = "\\d*";
4512 }
4513 if (opts !== undefined)
4514 for (var key in opts)
4515 numInput.setAttribute(key, opts[key]);
4516 wrapper.appendChild(numInput);
4517 wrapper.appendChild(arrowUp);
4518 wrapper.appendChild(arrowDown);
4519 return wrapper;
4520 }
4521 function getEventTarget(event) {
4522 if (typeof event.composedPath === "function") {
4523 var path = event.composedPath();
4524 return path[0];
4525 }
4526 return event.target;
4527 }
4528
4529 var do_nothing = function () { return undefined; };
4530 var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? "shorthand" : "longhand"][monthNumber]; };
4531 var revFormat = {
4532 D: do_nothing,
4533 F: function (dateObj, monthName, locale) {
4534 dateObj.setMonth(locale.months.longhand.indexOf(monthName));
4535 },
4536 G: function (dateObj, hour) {
4537 dateObj.setHours(parseFloat(hour));
4538 },
4539 H: function (dateObj, hour) {
4540 dateObj.setHours(parseFloat(hour));
4541 },
4542 J: function (dateObj, day) {
4543 dateObj.setDate(parseFloat(day));
4544 },
4545 K: function (dateObj, amPM, locale) {
4546 dateObj.setHours((dateObj.getHours() % 12) +
4547 12 * int(new RegExp(locale.amPM[1], "i").test(amPM)));
4548 },
4549 M: function (dateObj, shortMonth, locale) {
4550 dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));
4551 },
4552 S: function (dateObj, seconds) {
4553 dateObj.setSeconds(parseFloat(seconds));
4554 },
4555 U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },
4556 W: function (dateObj, weekNum) {
4557 var weekNumber = parseInt(weekNum);
4558 return new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);
4559 },
4560 Y: function (dateObj, year) {
4561 dateObj.setFullYear(parseFloat(year));
4562 },
4563 Z: function (_, ISODate) { return new Date(ISODate); },
4564 d: function (dateObj, day) {
4565 dateObj.setDate(parseFloat(day));
4566 },
4567 h: function (dateObj, hour) {
4568 dateObj.setHours(parseFloat(hour));
4569 },
4570 i: function (dateObj, minutes) {
4571 dateObj.setMinutes(parseFloat(minutes));
4572 },
4573 j: function (dateObj, day) {
4574 dateObj.setDate(parseFloat(day));
4575 },
4576 l: do_nothing,
4577 m: function (dateObj, month) {
4578 dateObj.setMonth(parseFloat(month) - 1);
4579 },
4580 n: function (dateObj, month) {
4581 dateObj.setMonth(parseFloat(month) - 1);
4582 },
4583 s: function (dateObj, seconds) {
4584 dateObj.setSeconds(parseFloat(seconds));
4585 },
4586 u: function (_, unixMillSeconds) {
4587 return new Date(parseFloat(unixMillSeconds));
4588 },
4589 w: do_nothing,
4590 y: function (dateObj, year) {
4591 dateObj.setFullYear(2000 + parseFloat(year));
4592 }
4593 };
4594 var tokenRegex = {
4595 D: "(\\w+)",
4596 F: "(\\w+)",
4597 G: "(\\d\\d|\\d)",
4598 H: "(\\d\\d|\\d)",
4599 J: "(\\d\\d|\\d)\\w+",
4600 K: "",
4601 M: "(\\w+)",
4602 S: "(\\d\\d|\\d)",
4603 U: "(.+)",
4604 W: "(\\d\\d|\\d)",
4605 Y: "(\\d{4})",
4606 Z: "(.+)",
4607 d: "(\\d\\d|\\d)",
4608 h: "(\\d\\d|\\d)",
4609 i: "(\\d\\d|\\d)",
4610 j: "(\\d\\d|\\d)",
4611 l: "(\\w+)",
4612 m: "(\\d\\d|\\d)",
4613 n: "(\\d\\d|\\d)",
4614 s: "(\\d\\d|\\d)",
4615 u: "(.+)",
4616 w: "(\\d\\d|\\d)",
4617 y: "(\\d{2})"
4618 };
4619 var formats = {
4620 // get the date in UTC
4621 Z: function (date) { return date.toISOString(); },
4622 // weekday name, short, e.g. Thu
4623 D: function (date, locale, options) {
4624 return locale.weekdays.shorthand[formats.w(date, locale, options)];
4625 },
4626 // full month name e.g. January
4627 F: function (date, locale, options) {
4628 return monthToStr(formats.n(date, locale, options) - 1, false, locale);
4629 },
4630 // padded hour 1-12
4631 G: function (date, locale, options) {
4632 return pad(formats.h(date, locale, options));
4633 },
4634 // hours with leading zero e.g. 03
4635 H: function (date) { return pad(date.getHours()); },
4636 // day (1-30) with ordinal suffix e.g. 1st, 2nd
4637 J: function (date, locale) {
4638 return locale.ordinal !== undefined
4639 ? date.getDate() + locale.ordinal(date.getDate())
4640 : date.getDate();
4641 },
4642 // AM/PM
4643 K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },
4644 // shorthand month e.g. Jan, Sep, Oct, etc
4645 M: function (date, locale) {
4646 return monthToStr(date.getMonth(), true, locale);
4647 },
4648 // seconds 00-59
4649 S: function (date) { return pad(date.getSeconds()); },
4650 // unix timestamp
4651 U: function (date) { return date.getTime() / 1000; },
4652 W: function (date, _, options) {
4653 return options.getWeek(date);
4654 },
4655 // full year e.g. 2016
4656 Y: function (date) { return date.getFullYear(); },
4657 // day in month, padded (01-30)
4658 d: function (date) { return pad(date.getDate()); },
4659 // hour from 1-12 (am/pm)
4660 h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },
4661 // minutes, padded with leading zero e.g. 09
4662 i: function (date) { return pad(date.getMinutes()); },
4663 // day in month (1-30)
4664 j: function (date) { return date.getDate(); },
4665 // weekday name, full, e.g. Thursday
4666 l: function (date, locale) {
4667 return locale.weekdays.longhand[date.getDay()];
4668 },
4669 // padded month number (01-12)
4670 m: function (date) { return pad(date.getMonth() + 1); },
4671 // the month number (1-12)
4672 n: function (date) { return date.getMonth() + 1; },
4673 // seconds 0-59
4674 s: function (date) { return date.getSeconds(); },
4675 // Unix Milliseconds
4676 u: function (date) { return date.getTime(); },
4677 // number of the day of the week
4678 w: function (date) { return date.getDay(); },
4679 // last two digits of year e.g. 16 for 2016
4680 y: function (date) { return String(date.getFullYear()).substring(2); }
4681 };
4682
4683 var createDateFormatter = function (_a) {
4684 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;
4685 return function (dateObj, frmt, overrideLocale) {
4686 var locale = overrideLocale || l10n;
4687 if (config.formatDate !== undefined) {
4688 return config.formatDate(dateObj, frmt, locale);
4689 }
4690 return frmt
4691 .split("")
4692 .map(function (c, i, arr) {
4693 return formats[c] && arr[i - 1] !== "\\"
4694 ? formats[c](dateObj, locale, config)
4695 : c !== "\\"
4696 ? c
4697 : "";
4698 })
4699 .join("");
4700 };
4701 };
4702 var createDateParser = function (_a) {
4703 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;
4704 return function (date, givenFormat, timeless, customLocale) {
4705 if (date !== 0 && !date)
4706 return undefined;
4707 var locale = customLocale || l10n;
4708 var parsedDate;
4709 var date_orig = date;
4710 if (date instanceof Date)
4711 parsedDate = new Date(date.getTime());
4712 else if (typeof date !== "string" &&
4713 date.toFixed !== undefined // timestamp
4714 )
4715 // create a copy
4716 parsedDate = new Date(date);
4717 else if (typeof date === "string") {
4718 // date string
4719 var format = givenFormat || (config || defaults).dateFormat;
4720 var datestr = String(date).trim();
4721 if (datestr === "today") {
4722 parsedDate = new Date();
4723 timeless = true;
4724 }
4725 else if (/Z$/.test(datestr) ||
4726 /GMT$/.test(datestr) // datestrings w/ timezone
4727 )
4728 parsedDate = new Date(date);
4729 else if (config && config.parseDate)
4730 parsedDate = config.parseDate(date, format);
4731 else {
4732 parsedDate =
4733 !config || !config.noCalendar
4734 ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)
4735 : new Date(new Date().setHours(0, 0, 0, 0));
4736 var matched = void 0, ops = [];
4737 for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
4738 var token_1 = format[i];
4739 var isBackSlash = token_1 === "\\";
4740 var escaped = format[i - 1] === "\\" || isBackSlash;
4741 if (tokenRegex[token_1] && !escaped) {
4742 regexStr += tokenRegex[token_1];
4743 var match = new RegExp(regexStr).exec(date);
4744 if (match && (matched = true)) {
4745 ops[token_1 !== "Y" ? "push" : "unshift"]({
4746 fn: revFormat[token_1],
4747 val: match[++matchIndex]
4748 });
4749 }
4750 }
4751 else if (!isBackSlash)
4752 regexStr += "."; // don't really care
4753 ops.forEach(function (_a) {
4754 var fn = _a.fn, val = _a.val;
4755 return (parsedDate = fn(parsedDate, val, locale) || parsedDate);
4756 });
4757 }
4758 parsedDate = matched ? parsedDate : undefined;
4759 }
4760 }
4761 /* istanbul ignore next */
4762 if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {
4763 config.errorHandler(new Error("Invalid date provided: " + date_orig));
4764 return undefined;
4765 }
4766 if (timeless === true)
4767 parsedDate.setHours(0, 0, 0, 0);
4768 return parsedDate;
4769 };
4770 };
4771 /**
4772 * Compute the difference in dates, measured in ms
4773 */
4774 function compareDates(date1, date2, timeless) {
4775 if (timeless === void 0) { timeless = true; }
4776 if (timeless !== false) {
4777 return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -
4778 new Date(date2.getTime()).setHours(0, 0, 0, 0));
4779 }
4780 return date1.getTime() - date2.getTime();
4781 }
4782 var isBetween = function (ts, ts1, ts2) {
4783 return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);
4784 };
4785 var duration = {
4786 DAY: 86400000
4787 };
4788
4789 if (typeof Object.assign !== "function") {
4790 Object.assign = function (target) {
4791 var args = [];
4792 for (var _i = 1; _i < arguments.length; _i++) {
4793 args[_i - 1] = arguments[_i];
4794 }
4795 if (!target) {
4796 throw TypeError("Cannot convert undefined or null to object");
4797 }
4798 var _loop_1 = function (source) {
4799 if (source) {
4800 Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });
4801 }
4802 };
4803 for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
4804 var source = args_1[_a];
4805 _loop_1(source);
4806 }
4807 return target;
4808 };
4809 }
4810
4811 var DEBOUNCED_CHANGE_MS = 300;
4812 function FlatpickrInstance(element, instanceConfig) {
4813 var self = {
4814 config: __assign({}, flatpickr.defaultConfig),
4815 l10n: english
4816 };
4817 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
4818 self._handlers = [];
4819 self._bind = bind;
4820 self._setHoursFromDate = setHoursFromDate;
4821 self._positionCalendar = positionCalendar;
4822 self.changeMonth = changeMonth;
4823 self.changeYear = changeYear;
4824 self.clear = clear;
4825 self.close = close;
4826 self._createElement = createElement;
4827 self.destroy = destroy;
4828 self.isEnabled = isEnabled;
4829 self.jumpToDate = jumpToDate;
4830 self.open = open;
4831 self.redraw = redraw;
4832 self.set = set;
4833 self.setDate = setDate;
4834 self.toggle = toggle;
4835 function setupHelperFunctions() {
4836 self.utils = {
4837 getDaysInMonth: function (month, yr) {
4838 if (month === void 0) { month = self.currentMonth; }
4839 if (yr === void 0) { yr = self.currentYear; }
4840 if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))
4841 return 29;
4842 return self.l10n.daysInMonth[month];
4843 }
4844 };
4845 }
4846 function init() {
4847 self.element = self.input = element;
4848 self.isOpen = false;
4849 parseConfig();
4850 setupLocale();
4851 setupInputs();
4852 setupDates();
4853 setupHelperFunctions();
4854 if (!self.isMobile)
4855 build();
4856 bindEvents();
4857 if (self.selectedDates.length || self.config.noCalendar) {
4858 if (self.config.enableTime) {
4859 setHoursFromDate(self.config.noCalendar
4860 ? self.latestSelectedDateObj || self.config.minDate
4861 : undefined);
4862 }
4863 updateValue(false);
4864 }
4865 setCalendarWidth();
4866 self.showTimeInput =
4867 self.selectedDates.length > 0 || self.config.noCalendar;
4868 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
4869 /* TODO: investigate this further
4870
4871 Currently, there is weird positioning behavior in safari causing pages
4872 to scroll up. https://github.com/chmln/flatpickr/issues/563
4873
4874 However, most browsers are not Safari and positioning is expensive when used
4875 in scale. https://github.com/chmln/flatpickr/issues/1096
4876 */
4877 if (!self.isMobile && isSafari) {
4878 positionCalendar();
4879 }
4880 triggerEvent("onReady");
4881 }
4882 function bindToInstance(fn) {
4883 return fn.bind(self);
4884 }
4885 function setCalendarWidth() {
4886 var config = self.config;
4887 if (config.weekNumbers === false && config.showMonths === 1)
4888 return;
4889 else if (config.noCalendar !== true) {
4890 window.requestAnimationFrame(function () {
4891 if (self.calendarContainer !== undefined) {
4892 self.calendarContainer.style.visibility = "hidden";
4893 self.calendarContainer.style.display = "block";
4894 }
4895 if (self.daysContainer !== undefined) {
4896 var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;
4897 self.daysContainer.style.width = daysWidth + "px";
4898 self.calendarContainer.style.width =
4899 daysWidth +
4900 (self.weekWrapper !== undefined
4901 ? self.weekWrapper.offsetWidth
4902 : 0) +
4903 "px";
4904 self.calendarContainer.style.removeProperty("visibility");
4905 self.calendarContainer.style.removeProperty("display");
4906 }
4907 });
4908 }
4909 }
4910 /**
4911 * The handler for all events targeting the time inputs
4912 */
4913 function updateTime(e) {
4914 if (self.selectedDates.length === 0) {
4915 setDefaultTime();
4916 }
4917 if (e !== undefined && e.type !== "blur") {
4918 timeWrapper(e);
4919 }
4920 var prevValue = self._input.value;
4921 setHoursFromInputs();
4922 updateValue();
4923 if (self._input.value !== prevValue) {
4924 self._debouncedChange();
4925 }
4926 }
4927 function ampm2military(hour, amPM) {
4928 return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);
4929 }
4930 function military2ampm(hour) {
4931 switch (hour % 24) {
4932 case 0:
4933 case 12:
4934 return 12;
4935 default:
4936 return hour % 12;
4937 }
4938 }
4939 /**
4940 * Syncs the selected date object time with user's time input
4941 */
4942 function setHoursFromInputs() {
4943 if (self.hourElement === undefined || self.minuteElement === undefined)
4944 return;
4945 var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined
4946 ? (parseInt(self.secondElement.value, 10) || 0) % 60
4947 : 0;
4948 if (self.amPM !== undefined) {
4949 hours = ampm2military(hours, self.amPM.textContent);
4950 }
4951 var limitMinHours = self.config.minTime !== undefined ||
4952 (self.config.minDate &&
4953 self.minDateHasTime &&
4954 self.latestSelectedDateObj &&
4955 compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===
4956 0);
4957 var limitMaxHours = self.config.maxTime !== undefined ||
4958 (self.config.maxDate &&
4959 self.maxDateHasTime &&
4960 self.latestSelectedDateObj &&
4961 compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===
4962 0);
4963 if (limitMaxHours) {
4964 var maxTime = self.config.maxTime !== undefined
4965 ? self.config.maxTime
4966 : self.config.maxDate;
4967 hours = Math.min(hours, maxTime.getHours());
4968 if (hours === maxTime.getHours())
4969 minutes = Math.min(minutes, maxTime.getMinutes());
4970 if (minutes === maxTime.getMinutes())
4971 seconds = Math.min(seconds, maxTime.getSeconds());
4972 }
4973 if (limitMinHours) {
4974 var minTime = self.config.minTime !== undefined
4975 ? self.config.minTime
4976 : self.config.minDate;
4977 hours = Math.max(hours, minTime.getHours());
4978 if (hours === minTime.getHours())
4979 minutes = Math.max(minutes, minTime.getMinutes());
4980 if (minutes === minTime.getMinutes())
4981 seconds = Math.max(seconds, minTime.getSeconds());
4982 }
4983 setHours(hours, minutes, seconds);
4984 }
4985 /**
4986 * Syncs time input values with a date
4987 */
4988 function setHoursFromDate(dateObj) {
4989 var date = dateObj || self.latestSelectedDateObj;
4990 if (date)
4991 setHours(date.getHours(), date.getMinutes(), date.getSeconds());
4992 }
4993 function setDefaultHours() {
4994 var hours = self.config.defaultHour;
4995 var minutes = self.config.defaultMinute;
4996 var seconds = self.config.defaultSeconds;
4997 if (self.config.minDate !== undefined) {
4998 var min_hr = self.config.minDate.getHours();
4999 var min_minutes = self.config.minDate.getMinutes();
5000 hours = Math.max(hours, min_hr);
5001 if (hours === min_hr)
5002 minutes = Math.max(min_minutes, minutes);
5003 if (hours === min_hr && minutes === min_minutes)
5004 seconds = self.config.minDate.getSeconds();
5005 }
5006 if (self.config.maxDate !== undefined) {
5007 var max_hr = self.config.maxDate.getHours();
5008 var max_minutes = self.config.maxDate.getMinutes();
5009 hours = Math.min(hours, max_hr);
5010 if (hours === max_hr)
5011 minutes = Math.min(max_minutes, minutes);
5012 if (hours === max_hr && minutes === max_minutes)
5013 seconds = self.config.maxDate.getSeconds();
5014 }
5015 setHours(hours, minutes, seconds);
5016 }
5017 /**
5018 * Sets the hours, minutes, and optionally seconds
5019 * of the latest selected date object and the
5020 * corresponding time inputs
5021 * @param {Number} hours the hour. whether its military
5022 * or am-pm gets inferred from config
5023 * @param {Number} minutes the minutes
5024 * @param {Number} seconds the seconds (optional)
5025 */
5026 function setHours(hours, minutes, seconds) {
5027 if (self.latestSelectedDateObj !== undefined) {
5028 self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);
5029 }
5030 if (!self.hourElement || !self.minuteElement || self.isMobile)
5031 return;
5032 self.hourElement.value = pad(!self.config.time_24hr
5033 ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)
5034 : hours);
5035 self.minuteElement.value = pad(minutes);
5036 if (self.amPM !== undefined)
5037 self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];
5038 if (self.secondElement !== undefined)
5039 self.secondElement.value = pad(seconds);
5040 }
5041 /**
5042 * Handles the year input and incrementing events
5043 * @param {Event} event the keyup or increment event
5044 */
5045 function onYearInput(event) {
5046 var year = parseInt(event.target.value) + (event.delta || 0);
5047 if (year / 1000 > 1 ||
5048 (event.key === "Enter" && !/[^\d]/.test(year.toString()))) {
5049 changeYear(year);
5050 }
5051 }
5052 /**
5053 * Essentially addEventListener + tracking
5054 * @param {Element} element the element to addEventListener to
5055 * @param {String} event the event name
5056 * @param {Function} handler the event handler
5057 */
5058 function bind(element, event, handler, options) {
5059 if (event instanceof Array)
5060 return event.forEach(function (ev) { return bind(element, ev, handler, options); });
5061 if (element instanceof Array)
5062 return element.forEach(function (el) { return bind(el, event, handler, options); });
5063 element.addEventListener(event, handler, options);
5064 self._handlers.push({
5065 element: element,
5066 event: event,
5067 handler: handler,
5068 options: options
5069 });
5070 }
5071 /**
5072 * A mousedown handler which mimics click.
5073 * Minimizes latency, since we don't need to wait for mouseup in most cases.
5074 * Also, avoids handling right clicks.
5075 *
5076 * @param {Function} handler the event handler
5077 */
5078 function onClick(handler) {
5079 return function (evt) {
5080 evt.which === 1 && handler(evt);
5081 };
5082 }
5083 function triggerChange() {
5084 triggerEvent("onChange");
5085 }
5086 /**
5087 * Adds all the necessary event listeners
5088 */
5089 function bindEvents() {
5090 if (self.config.wrap) {
5091 ["open", "close", "toggle", "clear"].forEach(function (evt) {
5092 Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) {
5093 return bind(el, "click", self[evt]);
5094 });
5095 });
5096 }
5097 if (self.isMobile) {
5098 setupMobile();
5099 return;
5100 }
5101 var debouncedResize = debounce(onResize, 50);
5102 self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);
5103 if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))
5104 bind(self.daysContainer, "mouseover", function (e) {
5105 if (self.config.mode === "range")
5106 onMouseOver(e.target);
5107 });
5108 bind(window.document.body, "keydown", onKeyDown);
5109 if (!self.config.static)
5110 bind(self._input, "keydown", onKeyDown);
5111 if (!self.config.inline && !self.config.static)
5112 bind(window, "resize", debouncedResize);
5113 if (window.ontouchstart !== undefined)
5114 bind(window.document, "click", documentClick);
5115 else
5116 bind(window.document, "mousedown", onClick(documentClick));
5117 bind(window.document, "focus", documentClick, { capture: true });
5118 if (self.config.clickOpens === true) {
5119 bind(self._input, "focus", self.open);
5120 bind(self._input, "mousedown", onClick(self.open));
5121 }
5122 if (self.daysContainer !== undefined) {
5123 bind(self.monthNav, "mousedown", onClick(onMonthNavClick));
5124 bind(self.monthNav, ["keyup", "increment"], onYearInput);
5125 bind(self.daysContainer, "mousedown", onClick(selectDate));
5126 }
5127 if (self.timeContainer !== undefined &&
5128 self.minuteElement !== undefined &&
5129 self.hourElement !== undefined) {
5130 var selText = function (e) {
5131 return e.target.select();
5132 };
5133 bind(self.timeContainer, ["increment"], updateTime);
5134 bind(self.timeContainer, "blur", updateTime, { capture: true });
5135 bind(self.timeContainer, "mousedown", onClick(timeIncrement));
5136 bind([self.hourElement, self.minuteElement], ["focus", "click"], selText);
5137 if (self.secondElement !== undefined)
5138 bind(self.secondElement, "focus", function () { return self.secondElement && self.secondElement.select(); });
5139 if (self.amPM !== undefined) {
5140 bind(self.amPM, "mousedown", onClick(function (e) {
5141 updateTime(e);
5142 triggerChange();
5143 }));
5144 }
5145 }
5146 }
5147 /**
5148 * Set the calendar view to a particular date.
5149 * @param {Date} jumpDate the date to set the view to
5150 */
5151 function jumpToDate(jumpDate) {
5152 var jumpTo = jumpDate !== undefined
5153 ? self.parseDate(jumpDate)
5154 : self.latestSelectedDateObj ||
5155 (self.config.minDate && self.config.minDate > self.now
5156 ? self.config.minDate
5157 : self.config.maxDate && self.config.maxDate < self.now
5158 ? self.config.maxDate
5159 : self.now);
5160 try {
5161 if (jumpTo !== undefined) {
5162 self.currentYear = jumpTo.getFullYear();
5163 self.currentMonth = jumpTo.getMonth();
5164 }
5165 }
5166 catch (e) {
5167 /* istanbul ignore next */
5168 e.message = "Invalid date supplied: " + jumpTo;
5169 self.config.errorHandler(e);
5170 }
5171 self.redraw();
5172 }
5173 /**
5174 * The up/down arrow handler for time inputs
5175 * @param {Event} e the click event
5176 */
5177 function timeIncrement(e) {
5178 if (~e.target.className.indexOf("arrow"))
5179 incrementNumInput(e, e.target.classList.contains("arrowUp") ? 1 : -1);
5180 }
5181 /**
5182 * Increments/decrements the value of input associ-
5183 * ated with the up/down arrow by dispatching an
5184 * "increment" event on the input.
5185 *
5186 * @param {Event} e the click event
5187 * @param {Number} delta the diff (usually 1 or -1)
5188 * @param {Element} inputElem the input element
5189 */
5190 function incrementNumInput(e, delta, inputElem) {
5191 var target = e && e.target;
5192 var input = inputElem ||
5193 (target && target.parentNode && target.parentNode.firstChild);
5194 var event = createEvent("increment");
5195 event.delta = delta;
5196 input && input.dispatchEvent(event);
5197 }
5198 function build() {
5199 var fragment = window.document.createDocumentFragment();
5200 self.calendarContainer = createElement("div", "flatpickr-calendar");
5201 self.calendarContainer.tabIndex = -1;
5202 if (!self.config.noCalendar) {
5203 fragment.appendChild(buildMonthNav());
5204 self.innerContainer = createElement("div", "flatpickr-innerContainer");
5205 if (self.config.weekNumbers) {
5206 var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;
5207 self.innerContainer.appendChild(weekWrapper);
5208 self.weekNumbers = weekNumbers;
5209 self.weekWrapper = weekWrapper;
5210 }
5211 self.rContainer = createElement("div", "flatpickr-rContainer");
5212 self.rContainer.appendChild(buildWeekdays());
5213 if (!self.daysContainer) {
5214 self.daysContainer = createElement("div", "flatpickr-days");
5215 self.daysContainer.tabIndex = -1;
5216 }
5217 buildDays();
5218 self.rContainer.appendChild(self.daysContainer);
5219 self.innerContainer.appendChild(self.rContainer);
5220 fragment.appendChild(self.innerContainer);
5221 }
5222 if (self.config.enableTime) {
5223 fragment.appendChild(buildTime());
5224 }
5225 toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range");
5226 toggleClass(self.calendarContainer, "animate", self.config.animate === true);
5227 toggleClass(self.calendarContainer, "multiMonth", self.config.showMonths > 1);
5228 self.calendarContainer.appendChild(fragment);
5229 var customAppend = self.config.appendTo !== undefined &&
5230 self.config.appendTo.nodeType !== undefined;
5231 if (self.config.inline || self.config.static) {
5232 self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
5233 if (self.config.inline) {
5234 if (!customAppend && self.element.parentNode)
5235 self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);
5236 else if (self.config.appendTo !== undefined)
5237 self.config.appendTo.appendChild(self.calendarContainer);
5238 }
5239 if (self.config.static) {
5240 var wrapper = createElement("div", "flatpickr-wrapper");
5241 if (self.element.parentNode)
5242 self.element.parentNode.insertBefore(wrapper, self.element);
5243 wrapper.appendChild(self.element);
5244 if (self.altInput)
5245 wrapper.appendChild(self.altInput);
5246 wrapper.appendChild(self.calendarContainer);
5247 }
5248 }
5249 if (!self.config.static && !self.config.inline)
5250 (self.config.appendTo !== undefined
5251 ? self.config.appendTo
5252 : window.document.body).appendChild(self.calendarContainer);
5253 }
5254 function createDay(className, date, dayNumber, i) {
5255 var dateIsEnabled = isEnabled(date, true), dayElement = createElement("span", "flatpickr-day " + className, date.getDate().toString());
5256 dayElement.dateObj = date;
5257 dayElement.$i = i;
5258 dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));
5259 if (className.indexOf("hidden") === -1 &&
5260 compareDates(date, self.now) === 0) {
5261 self.todayDateElem = dayElement;
5262 dayElement.classList.add("today");
5263 dayElement.setAttribute("aria-current", "date");
5264 }
5265 if (dateIsEnabled) {
5266 dayElement.tabIndex = -1;
5267 if (isDateSelected(date)) {
5268 dayElement.classList.add("selected");
5269 self.selectedDateElem = dayElement;
5270 if (self.config.mode === "range") {
5271 toggleClass(dayElement, "startRange", self.selectedDates[0] &&
5272 compareDates(date, self.selectedDates[0], true) === 0);
5273 toggleClass(dayElement, "endRange", self.selectedDates[1] &&
5274 compareDates(date, self.selectedDates[1], true) === 0);
5275 if (className === "nextMonthDay")
5276 dayElement.classList.add("inRange");
5277 }
5278 }
5279 }
5280 else {
5281 dayElement.classList.add("disabled");
5282 }
5283 if (self.config.mode === "range") {
5284 if (isDateInRange(date) && !isDateSelected(date))
5285 dayElement.classList.add("inRange");
5286 }
5287 if (self.weekNumbers &&
5288 self.config.showMonths === 1 &&
5289 className !== "prevMonthDay" &&
5290 dayNumber % 7 === 1) {
5291 self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='flatpickr-day'>" + self.config.getWeek(date) + "</span>");
5292 }
5293 triggerEvent("onDayCreate", dayElement);
5294 return dayElement;
5295 }
5296 function focusOnDayElem(targetNode) {
5297 targetNode.focus();
5298 if (self.config.mode === "range")
5299 onMouseOver(targetNode);
5300 }
5301 function getFirstAvailableDay(delta) {
5302 var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;
5303 var endMonth = delta > 0 ? self.config.showMonths : -1;
5304 for (var m = startMonth; m != endMonth; m += delta) {
5305 var month = self.daysContainer.children[m];
5306 var startIndex = delta > 0 ? 0 : month.children.length - 1;
5307 var endIndex = delta > 0 ? month.children.length : -1;
5308 for (var i = startIndex; i != endIndex; i += delta) {
5309 var c = month.children[i];
5310 if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj))
5311 return c;
5312 }
5313 }
5314 return undefined;
5315 }
5316 function getNextAvailableDay(current, delta) {
5317 var givenMonth = current.className.indexOf("Month") === -1
5318 ? current.dateObj.getMonth()
5319 : self.currentMonth;
5320 var endMonth = delta > 0 ? self.config.showMonths : -1;
5321 var loopDelta = delta > 0 ? 1 : -1;
5322 for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {
5323 var month = self.daysContainer.children[m];
5324 var startIndex = givenMonth - self.currentMonth === m
5325 ? current.$i + delta
5326 : delta < 0
5327 ? month.children.length - 1
5328 : 0;
5329 var numMonthDays = month.children.length;
5330 for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {
5331 var c = month.children[i];
5332 if (c.className.indexOf("hidden") === -1 &&
5333 isEnabled(c.dateObj) &&
5334 Math.abs(current.$i - i) >= Math.abs(delta))
5335 return focusOnDayElem(c);
5336 }
5337 }
5338 self.changeMonth(loopDelta);
5339 focusOnDay(getFirstAvailableDay(loopDelta), 0);
5340 return undefined;
5341 }
5342 function focusOnDay(current, offset) {
5343 var dayFocused = isInView(document.activeElement || document.body);
5344 var startElem = current !== undefined
5345 ? current
5346 : dayFocused
5347 ? document.activeElement
5348 : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)
5349 ? self.selectedDateElem
5350 : self.todayDateElem !== undefined && isInView(self.todayDateElem)
5351 ? self.todayDateElem
5352 : getFirstAvailableDay(offset > 0 ? 1 : -1);
5353 if (startElem === undefined)
5354 return self._input.focus();
5355 if (!dayFocused)
5356 return focusOnDayElem(startElem);
5357 getNextAvailableDay(startElem, offset);
5358 }
5359 function buildMonthDays(year, month) {
5360 var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;
5361 var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12);
5362 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";
5363 var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;
5364 // prepend days from the ending of previous month
5365 for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {
5366 days.appendChild(createDay(prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));
5367 }
5368 // Start at 1 since there is no 0th day
5369 for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
5370 days.appendChild(createDay("", new Date(year, month, dayNumber), dayNumber, dayIndex));
5371 }
5372 // append days from the next month
5373 for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&
5374 (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {
5375 days.appendChild(createDay(nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));
5376 }
5377 //updateNavigationCurrentMonth();
5378 var dayContainer = createElement("div", "dayContainer");
5379 dayContainer.appendChild(days);
5380 return dayContainer;
5381 }
5382 function buildDays() {
5383 if (self.daysContainer === undefined) {
5384 return;
5385 }
5386 clearNode(self.daysContainer);
5387 // TODO: week numbers for each month
5388 if (self.weekNumbers)
5389 clearNode(self.weekNumbers);
5390 var frag = document.createDocumentFragment();
5391 for (var i = 0; i < self.config.showMonths; i++) {
5392 var d = new Date(self.currentYear, self.currentMonth, 1);
5393 d.setMonth(self.currentMonth + i);
5394 frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));
5395 }
5396 self.daysContainer.appendChild(frag);
5397 self.days = self.daysContainer.firstChild;
5398 if (self.config.mode === "range" && self.selectedDates.length === 1) {
5399 onMouseOver();
5400 }
5401 }
5402 function buildMonth() {
5403 var container = createElement("div", "flatpickr-month");
5404 var monthNavFragment = window.document.createDocumentFragment();
5405 var monthElement = createElement("span", "cur-month");
5406 var yearInput = createNumberInput("cur-year", { tabindex: "-1" });
5407 var yearElement = yearInput.getElementsByTagName("input")[0];
5408 yearElement.setAttribute("aria-label", self.l10n.yearAriaLabel);
5409 if (self.config.minDate) {
5410 yearElement.setAttribute("min", self.config.minDate.getFullYear().toString());
5411 }
5412 if (self.config.maxDate) {
5413 yearElement.setAttribute("max", self.config.maxDate.getFullYear().toString());
5414 yearElement.disabled =
5415 !!self.config.minDate &&
5416 self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
5417 }
5418 var currentMonth = createElement("div", "flatpickr-current-month");
5419 currentMonth.appendChild(monthElement);
5420 currentMonth.appendChild(yearInput);
5421 monthNavFragment.appendChild(currentMonth);
5422 container.appendChild(monthNavFragment);
5423 return {
5424 container: container,
5425 yearElement: yearElement,
5426 monthElement: monthElement
5427 };
5428 }
5429 function buildMonths() {
5430 clearNode(self.monthNav);
5431 self.monthNav.appendChild(self.prevMonthNav);
5432 if (self.config.showMonths) {
5433 self.yearElements = [];
5434 self.monthElements = [];
5435 }
5436 for (var m = self.config.showMonths; m--;) {
5437 var month = buildMonth();
5438 self.yearElements.push(month.yearElement);
5439 self.monthElements.push(month.monthElement);
5440 self.monthNav.appendChild(month.container);
5441 }
5442 self.monthNav.appendChild(self.nextMonthNav);
5443 }
5444 function buildMonthNav() {
5445 self.monthNav = createElement("div", "flatpickr-months");
5446 self.yearElements = [];
5447 self.monthElements = [];
5448 self.prevMonthNav = createElement("span", "flatpickr-prev-month");
5449 self.prevMonthNav.innerHTML = self.config.prevArrow;
5450 self.nextMonthNav = createElement("span", "flatpickr-next-month");
5451 self.nextMonthNav.innerHTML = self.config.nextArrow;
5452 buildMonths();
5453 Object.defineProperty(self, "_hidePrevMonthArrow", {
5454 get: function () { return self.__hidePrevMonthArrow; },
5455 set: function (bool) {
5456 if (self.__hidePrevMonthArrow !== bool) {
5457 toggleClass(self.prevMonthNav, "disabled", bool);
5458 self.__hidePrevMonthArrow = bool;
5459 }
5460 }
5461 });
5462 Object.defineProperty(self, "_hideNextMonthArrow", {
5463 get: function () { return self.__hideNextMonthArrow; },
5464 set: function (bool) {
5465 if (self.__hideNextMonthArrow !== bool) {
5466 toggleClass(self.nextMonthNav, "disabled", bool);
5467 self.__hideNextMonthArrow = bool;
5468 }
5469 }
5470 });
5471 self.currentYearElement = self.yearElements[0];
5472 updateNavigationCurrentMonth();
5473 return self.monthNav;
5474 }
5475 function buildTime() {
5476 self.calendarContainer.classList.add("hasTime");
5477 if (self.config.noCalendar)
5478 self.calendarContainer.classList.add("noCalendar");
5479 self.timeContainer = createElement("div", "flatpickr-time");
5480 self.timeContainer.tabIndex = -1;
5481 var separator = createElement("span", "flatpickr-time-separator", ":");
5482 var hourInput = createNumberInput("flatpickr-hour");
5483 self.hourElement = hourInput.getElementsByTagName("input")[0];
5484 var minuteInput = createNumberInput("flatpickr-minute");
5485 self.minuteElement = minuteInput.getElementsByTagName("input")[0];
5486 self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;
5487 self.hourElement.value = pad(self.latestSelectedDateObj
5488 ? self.latestSelectedDateObj.getHours()
5489 : self.config.time_24hr
5490 ? self.config.defaultHour
5491 : military2ampm(self.config.defaultHour));
5492 self.minuteElement.value = pad(self.latestSelectedDateObj
5493 ? self.latestSelectedDateObj.getMinutes()
5494 : self.config.defaultMinute);
5495 self.hourElement.setAttribute("step", self.config.hourIncrement.toString());
5496 self.minuteElement.setAttribute("step", self.config.minuteIncrement.toString());
5497 self.hourElement.setAttribute("min", self.config.time_24hr ? "0" : "1");
5498 self.hourElement.setAttribute("max", self.config.time_24hr ? "23" : "12");
5499 self.minuteElement.setAttribute("min", "0");
5500 self.minuteElement.setAttribute("max", "59");
5501 self.timeContainer.appendChild(hourInput);
5502 self.timeContainer.appendChild(separator);
5503 self.timeContainer.appendChild(minuteInput);
5504 if (self.config.time_24hr)
5505 self.timeContainer.classList.add("time24hr");
5506 if (self.config.enableSeconds) {
5507 self.timeContainer.classList.add("hasSeconds");
5508 var secondInput = createNumberInput("flatpickr-second");
5509 self.secondElement = secondInput.getElementsByTagName("input")[0];
5510 self.secondElement.value = pad(self.latestSelectedDateObj
5511 ? self.latestSelectedDateObj.getSeconds()
5512 : self.config.defaultSeconds);
5513 self.secondElement.setAttribute("step", self.minuteElement.getAttribute("step"));
5514 self.secondElement.setAttribute("min", "0");
5515 self.secondElement.setAttribute("max", "59");
5516 self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
5517 self.timeContainer.appendChild(secondInput);
5518 }
5519 if (!self.config.time_24hr) {
5520 // add self.amPM if appropriate
5521 self.amPM = createElement("span", "flatpickr-am-pm", self.l10n.amPM[int((self.latestSelectedDateObj
5522 ? self.hourElement.value
5523 : self.config.defaultHour) > 11)]);
5524 self.amPM.title = self.l10n.toggleTitle;
5525 self.amPM.tabIndex = -1;
5526 self.timeContainer.appendChild(self.amPM);
5527 }
5528 return self.timeContainer;
5529 }
5530 function buildWeekdays() {
5531 if (!self.weekdayContainer)
5532 self.weekdayContainer = createElement("div", "flatpickr-weekdays");
5533 else
5534 clearNode(self.weekdayContainer);
5535 for (var i = self.config.showMonths; i--;) {
5536 var container = createElement("div", "flatpickr-weekdaycontainer");
5537 self.weekdayContainer.appendChild(container);
5538 }
5539 updateWeekdays();
5540 return self.weekdayContainer;
5541 }
5542 function updateWeekdays() {
5543 var firstDayOfWeek = self.l10n.firstDayOfWeek;
5544 var weekdays = self.l10n.weekdays.shorthand.slice();
5545 if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
5546 weekdays = weekdays.splice(firstDayOfWeek, weekdays.length).concat(weekdays.splice(0, firstDayOfWeek));
5547 }
5548 for (var i = self.config.showMonths; i--;) {
5549 self.weekdayContainer.children[i].innerHTML = "\n <span class='flatpickr-weekday'>\n " + weekdays.join("</span><span class='flatpickr-weekday'>") + "\n </span>\n ";
5550 }
5551 }
5552 /* istanbul ignore next */
5553 function buildWeeks() {
5554 self.calendarContainer.classList.add("hasWeeks");
5555 var weekWrapper = createElement("div", "flatpickr-weekwrapper");
5556 weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
5557 var weekNumbers = createElement("div", "flatpickr-weeks");
5558 weekWrapper.appendChild(weekNumbers);
5559 return {
5560 weekWrapper: weekWrapper,
5561 weekNumbers: weekNumbers
5562 };
5563 }
5564 function changeMonth(value, is_offset) {
5565 if (is_offset === void 0) { is_offset = true; }
5566 var delta = is_offset ? value : value - self.currentMonth;
5567 if ((delta < 0 && self._hidePrevMonthArrow === true) ||
5568 (delta > 0 && self._hideNextMonthArrow === true))
5569 return;
5570 self.currentMonth += delta;
5571 if (self.currentMonth < 0 || self.currentMonth > 11) {
5572 self.currentYear += self.currentMonth > 11 ? 1 : -1;
5573 self.currentMonth = (self.currentMonth + 12) % 12;
5574 triggerEvent("onYearChange");
5575 }
5576 buildDays();
5577 triggerEvent("onMonthChange");
5578 updateNavigationCurrentMonth();
5579 }
5580 function clear(triggerChangeEvent, toInitial) {
5581 if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }
5582 if (toInitial === void 0) { toInitial = true; }
5583 self.input.value = "";
5584 if (self.altInput !== undefined)
5585 self.altInput.value = "";
5586 if (self.mobileInput !== undefined)
5587 self.mobileInput.value = "";
5588 self.selectedDates = [];
5589 self.latestSelectedDateObj = undefined;
5590 if (toInitial === true) {
5591 self.currentYear = self._initialDate.getFullYear();
5592 self.currentMonth = self._initialDate.getMonth();
5593 }
5594 self.showTimeInput = false;
5595 if (self.config.enableTime === true) {
5596 setDefaultHours();
5597 }
5598 self.redraw();
5599 if (triggerChangeEvent)
5600 // triggerChangeEvent is true (default) or an Event
5601 triggerEvent("onChange");
5602 }
5603 function close() {
5604 self.isOpen = false;
5605 if (!self.isMobile) {
5606 if (self.calendarContainer !== undefined) {
5607 self.calendarContainer.classList.remove("open");
5608 }
5609 if (self._input !== undefined) {
5610 self._input.classList.remove("active");
5611 }
5612 }
5613 triggerEvent("onClose");
5614 }
5615 function destroy() {
5616 if (self.config !== undefined)
5617 triggerEvent("onDestroy");
5618 for (var i = self._handlers.length; i--;) {
5619 var h = self._handlers[i];
5620 h.element.removeEventListener(h.event, h.handler, h.options);
5621 }
5622 self._handlers = [];
5623 if (self.mobileInput) {
5624 if (self.mobileInput.parentNode)
5625 self.mobileInput.parentNode.removeChild(self.mobileInput);
5626 self.mobileInput = undefined;
5627 }
5628 else if (self.calendarContainer && self.calendarContainer.parentNode) {
5629 if (self.config.static && self.calendarContainer.parentNode) {
5630 var wrapper = self.calendarContainer.parentNode;
5631 wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);
5632 if (wrapper.parentNode) {
5633 while (wrapper.firstChild)
5634 wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);
5635 wrapper.parentNode.removeChild(wrapper);
5636 }
5637 }
5638 else
5639 self.calendarContainer.parentNode.removeChild(self.calendarContainer);
5640 }
5641 if (self.altInput) {
5642 self.input.type = "text";
5643 if (self.altInput.parentNode)
5644 self.altInput.parentNode.removeChild(self.altInput);
5645 delete self.altInput;
5646 }
5647 if (self.input) {
5648 self.input.type = self.input._type;
5649 self.input.classList.remove("flatpickr-input");
5650 self.input.removeAttribute("readonly");
5651 self.input.value = "";
5652 }
5653 [
5654 "_showTimeInput",
5655 "latestSelectedDateObj",
5656 "_hideNextMonthArrow",
5657 "_hidePrevMonthArrow",
5658 "__hideNextMonthArrow",
5659 "__hidePrevMonthArrow",
5660 "isMobile",
5661 "isOpen",
5662 "selectedDateElem",
5663 "minDateHasTime",
5664 "maxDateHasTime",
5665 "days",
5666 "daysContainer",
5667 "_input",
5668 "_positionElement",
5669 "innerContainer",
5670 "rContainer",
5671 "monthNav",
5672 "todayDateElem",
5673 "calendarContainer",
5674 "weekdayContainer",
5675 "prevMonthNav",
5676 "nextMonthNav",
5677 "currentMonthElement",
5678 "currentYearElement",
5679 "navigationCurrentMonth",
5680 "selectedDateElem",
5681 "config",
5682 ].forEach(function (k) {
5683 try {
5684 delete self[k];
5685 }
5686 catch (_) { }
5687 });
5688 }
5689 function isCalendarElem(elem) {
5690 if (self.config.appendTo && self.config.appendTo.contains(elem))
5691 return true;
5692 return self.calendarContainer.contains(elem);
5693 }
5694 function documentClick(e) {
5695 if (self.isOpen && !self.config.inline) {
5696 var eventTarget_1 = getEventTarget(e);
5697 var isCalendarElement = isCalendarElem(eventTarget_1);
5698 var isInput = eventTarget_1 === self.input ||
5699 eventTarget_1 === self.altInput ||
5700 self.element.contains(eventTarget_1) ||
5701 // web components
5702 // e.path is not present in all browsers. circumventing typechecks
5703 (e.path &&
5704 e.path.indexOf &&
5705 (~e.path.indexOf(self.input) ||
5706 ~e.path.indexOf(self.altInput)));
5707 var lostFocus = e.type === "blur"
5708 ? isInput &&
5709 e.relatedTarget &&
5710 !isCalendarElem(e.relatedTarget)
5711 : !isInput &&
5712 !isCalendarElement &&
5713 !isCalendarElem(e.relatedTarget);
5714 var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {
5715 return elem.contains(eventTarget_1);
5716 });
5717 if (lostFocus && isIgnored) {
5718 self.close();
5719 if (self.config.mode === "range" && self.selectedDates.length === 1) {
5720 self.clear(false);
5721 self.redraw();
5722 }
5723 }
5724 }
5725 }
5726 function changeYear(newYear) {
5727 if (!newYear ||
5728 (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||
5729 (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))
5730 return;
5731 var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;
5732 self.currentYear = newYearNum || self.currentYear;
5733 if (self.config.maxDate &&
5734 self.currentYear === self.config.maxDate.getFullYear()) {
5735 self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
5736 }
5737 else if (self.config.minDate &&
5738 self.currentYear === self.config.minDate.getFullYear()) {
5739 self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
5740 }
5741 if (isNewYear) {
5742 self.redraw();
5743 triggerEvent("onYearChange");
5744 }
5745 }
5746 function isEnabled(date, timeless) {
5747 if (timeless === void 0) { timeless = true; }
5748 var dateToCheck = self.parseDate(date, undefined, timeless); // timeless
5749 if ((self.config.minDate &&
5750 dateToCheck &&
5751 compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||
5752 (self.config.maxDate &&
5753 dateToCheck &&
5754 compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))
5755 return false;
5756 if (self.config.enable.length === 0 && self.config.disable.length === 0)
5757 return true;
5758 if (dateToCheck === undefined)
5759 return false;
5760 var bool = self.config.enable.length > 0, array = bool ? self.config.enable : self.config.disable;
5761 for (var i = 0, d = void 0; i < array.length; i++) {
5762 d = array[i];
5763 if (typeof d === "function" &&
5764 d(dateToCheck) // disabled by function
5765 )
5766 return bool;
5767 else if (d instanceof Date &&
5768 dateToCheck !== undefined &&
5769 d.getTime() === dateToCheck.getTime())
5770 // disabled by date
5771 return bool;
5772 else if (typeof d === "string" && dateToCheck !== undefined) {
5773 // disabled by date string
5774 var parsed = self.parseDate(d, undefined, true);
5775 return parsed && parsed.getTime() === dateToCheck.getTime()
5776 ? bool
5777 : !bool;
5778 }
5779 else if (
5780 // disabled by range
5781 typeof d === "object" &&
5782 dateToCheck !== undefined &&
5783 d.from &&
5784 d.to &&
5785 dateToCheck.getTime() >= d.from.getTime() &&
5786 dateToCheck.getTime() <= d.to.getTime())
5787 return bool;
5788 }
5789 return !bool;
5790 }
5791 function isInView(elem) {
5792 if (self.daysContainer !== undefined)
5793 return (elem.className.indexOf("hidden") === -1 &&
5794 self.daysContainer.contains(elem));
5795 return false;
5796 }
5797 function onKeyDown(e) {
5798 // e.key e.keyCode
5799 // "Backspace" 8
5800 // "Tab" 9
5801 // "Enter" 13
5802 // "Escape" (IE "Esc") 27
5803 // "ArrowLeft" (IE "Left") 37
5804 // "ArrowUp" (IE "Up") 38
5805 // "ArrowRight" (IE "Right") 39
5806 // "ArrowDown" (IE "Down") 40
5807 // "Delete" (IE "Del") 46
5808 var isInput = e.target === self._input;
5809 var allowInput = self.config.allowInput;
5810 var allowKeydown = self.isOpen && (!allowInput || !isInput);
5811 var allowInlineKeydown = self.config.inline && isInput && !allowInput;
5812 if (e.keyCode === 13 && isInput) {
5813 if (allowInput) {
5814 self.setDate(self._input.value, true, e.target === self.altInput
5815 ? self.config.altFormat
5816 : self.config.dateFormat);
5817 return e.target.blur();
5818 }
5819 else
5820 self.open();
5821 }
5822 else if (isCalendarElem(e.target) ||
5823 allowKeydown ||
5824 allowInlineKeydown) {
5825 var isTimeObj = !!self.timeContainer &&
5826 self.timeContainer.contains(e.target);
5827 switch (e.keyCode) {
5828 case 13:
5829 if (isTimeObj) {
5830 updateTime();
5831 focusAndClose();
5832 }
5833 else
5834 selectDate(e);
5835 break;
5836 case 27: // escape
5837 e.preventDefault();
5838 focusAndClose();
5839 break;
5840 case 8:
5841 case 46:
5842 if (isInput && !self.config.allowInput) {
5843 e.preventDefault();
5844 self.clear();
5845 }
5846 break;
5847 case 37:
5848 case 39:
5849 if (!isTimeObj) {
5850 e.preventDefault();
5851 if (self.daysContainer !== undefined &&
5852 (allowInput === false ||
5853 (document.activeElement && isInView(document.activeElement)))) {
5854 var delta_1 = e.keyCode === 39 ? 1 : -1;
5855 if (!e.ctrlKey)
5856 focusOnDay(undefined, delta_1);
5857 else {
5858 e.stopPropagation();
5859 changeMonth(delta_1);
5860 focusOnDay(getFirstAvailableDay(1), 0);
5861 }
5862 }
5863 }
5864 else if (self.hourElement)
5865 self.hourElement.focus();
5866 break;
5867 case 38:
5868 case 40:
5869 e.preventDefault();
5870 var delta = e.keyCode === 40 ? 1 : -1;
5871 if ((self.daysContainer && e.target.$i !== undefined) ||
5872 e.target === self.input) {
5873 if (e.ctrlKey) {
5874 e.stopPropagation();
5875 changeYear(self.currentYear - delta);
5876 focusOnDay(getFirstAvailableDay(1), 0);
5877 }
5878 else if (!isTimeObj)
5879 focusOnDay(undefined, delta * 7);
5880 }
5881 else if (self.config.enableTime) {
5882 if (!isTimeObj && self.hourElement)
5883 self.hourElement.focus();
5884 updateTime(e);
5885 self._debouncedChange();
5886 }
5887 break;
5888 case 9:
5889 if (isTimeObj) {
5890 var elems = [
5891 self.hourElement,
5892 self.minuteElement,
5893 self.secondElement,
5894 self.amPM,
5895 ].filter(function (x) { return x; });
5896 var i = elems.indexOf(e.target);
5897 if (i !== -1) {
5898 var target = elems[i + (e.shiftKey ? -1 : 1)];
5899 if (target !== undefined) {
5900 e.preventDefault();
5901 target.focus();
5902 }
5903 else if (e.shiftKey) {
5904 e.preventDefault();
5905 self._input.focus();
5906 }
5907 }
5908 }
5909 break;
5910 default:
5911 break;
5912 }
5913 }
5914 if (self.amPM !== undefined && e.target === self.amPM) {
5915 switch (e.key) {
5916 case self.l10n.amPM[0].charAt(0):
5917 case self.l10n.amPM[0].charAt(0).toLowerCase():
5918 self.amPM.textContent = self.l10n.amPM[0];
5919 setHoursFromInputs();
5920 updateValue();
5921 break;
5922 case self.l10n.amPM[1].charAt(0):
5923 case self.l10n.amPM[1].charAt(0).toLowerCase():
5924 self.amPM.textContent = self.l10n.amPM[1];
5925 setHoursFromInputs();
5926 updateValue();
5927 break;
5928 }
5929 }
5930 triggerEvent("onKeyDown", e);
5931 }
5932 function onMouseOver(elem) {
5933 if (self.selectedDates.length !== 1 ||
5934 (elem &&
5935 (!elem.classList.contains("flatpickr-day") ||
5936 elem.classList.contains("disabled"))))
5937 return;
5938 var hoverDate = elem
5939 ? elem.dateObj.getTime()
5940 : 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
5941 .lastChild.dateObj.getTime();
5942 var containsDisabled = false;
5943 var minRange = 0, maxRange = 0;
5944 for (var t = rangeStartDate; t < lastDate; t += duration.DAY) {
5945 if (!isEnabled(new Date(t), true)) {
5946 containsDisabled =
5947 containsDisabled || (t > rangeStartDate && t < rangeEndDate);
5948 if (t < initialDate && (!minRange || t > minRange))
5949 minRange = t;
5950 else if (t > initialDate && (!maxRange || t < maxRange))
5951 maxRange = t;
5952 }
5953 }
5954 for (var m = 0; m < self.config.showMonths; m++) {
5955 var month = self.daysContainer.children[m];
5956 var prevMonth = self.daysContainer.children[m - 1];
5957 var _loop_1 = function (i, l) {
5958 var dayElem = month.children[i], date = dayElem.dateObj;
5959 var timestamp = date.getTime();
5960 var outOfRange = (minRange > 0 && timestamp < minRange) ||
5961 (maxRange > 0 && timestamp > maxRange);
5962 if (outOfRange) {
5963 dayElem.classList.add("notAllowed");
5964 ["inRange", "startRange", "endRange"].forEach(function (c) {
5965 dayElem.classList.remove(c);
5966 });
5967 return "continue";
5968 }
5969 else if (containsDisabled && !outOfRange)
5970 return "continue";
5971 ["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) {
5972 dayElem.classList.remove(c);
5973 });
5974 if (elem !== undefined) {
5975 elem.classList.add(hoverDate < self.selectedDates[0].getTime()
5976 ? "startRange"
5977 : "endRange");
5978 if (month.contains(elem) ||
5979 !(m > 0 &&
5980 prevMonth &&
5981 prevMonth.lastChild.dateObj.getTime() >= timestamp)) {
5982 if (initialDate < hoverDate && timestamp === initialDate)
5983 dayElem.classList.add("startRange");
5984 else if (initialDate > hoverDate && timestamp === initialDate)
5985 dayElem.classList.add("endRange");
5986 if (timestamp >= minRange &&
5987 (maxRange === 0 || timestamp <= maxRange) &&
5988 isBetween(timestamp, initialDate, hoverDate))
5989 dayElem.classList.add("inRange");
5990 }
5991 }
5992 };
5993 for (var i = 0, l = month.children.length; i < l; i++) {
5994 _loop_1(i, l);
5995 }
5996 }
5997 }
5998 function onResize() {
5999 if (self.isOpen && !self.config.static && !self.config.inline)
6000 positionCalendar();
6001 }
6002 function setDefaultTime() {
6003 self.setDate(self.config.minDate !== undefined
6004 ? new Date(self.config.minDate.getTime())
6005 : new Date(), false);
6006 setDefaultHours();
6007 updateValue();
6008 }
6009 function open(e, positionElement) {
6010 if (positionElement === void 0) { positionElement = self._positionElement; }
6011 if (self.isMobile === true) {
6012 if (e) {
6013 e.preventDefault();
6014 e.target && e.target.blur();
6015 }
6016 if (self.mobileInput !== undefined) {
6017 self.mobileInput.focus();
6018 self.mobileInput.click();
6019 }
6020 triggerEvent("onOpen");
6021 return;
6022 }
6023 if (self._input.disabled || self.config.inline)
6024 return;
6025 var wasOpen = self.isOpen;
6026 self.isOpen = true;
6027 if (!wasOpen) {
6028 self.calendarContainer.classList.add("open");
6029 self._input.classList.add("active");
6030 triggerEvent("onOpen");
6031 positionCalendar(positionElement);
6032 }
6033 if (self.config.enableTime === true && self.config.noCalendar === true) {
6034 if (self.selectedDates.length === 0) {
6035 setDefaultTime();
6036 }
6037 if (self.config.allowInput === false &&
6038 (e === undefined ||
6039 !self.timeContainer.contains(e.relatedTarget))) {
6040 setTimeout(function () { return self.hourElement.select(); }, 50);
6041 }
6042 }
6043 }
6044 function minMaxDateSetter(type) {
6045 return function (date) {
6046 var dateObj = (self.config["_" + type + "Date"] = self.parseDate(date, self.config.dateFormat));
6047 var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
6048 if (dateObj !== undefined) {
6049 self[type === "min" ? "minDateHasTime" : "maxDateHasTime"] =
6050 dateObj.getHours() > 0 ||
6051 dateObj.getMinutes() > 0 ||
6052 dateObj.getSeconds() > 0;
6053 }
6054 if (self.selectedDates) {
6055 self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });
6056 if (!self.selectedDates.length && type === "min")
6057 setHoursFromDate(dateObj);
6058 updateValue();
6059 }
6060 if (self.daysContainer) {
6061 redraw();
6062 if (dateObj !== undefined)
6063 self.currentYearElement[type] = dateObj.getFullYear().toString();
6064 else
6065 self.currentYearElement.removeAttribute(type);
6066 self.currentYearElement.disabled =
6067 !!inverseDateObj &&
6068 dateObj !== undefined &&
6069 inverseDateObj.getFullYear() === dateObj.getFullYear();
6070 }
6071 };
6072 }
6073 function parseConfig() {
6074 var boolOpts = [
6075 "wrap",
6076 "weekNumbers",
6077 "allowInput",
6078 "clickOpens",
6079 "time_24hr",
6080 "enableTime",
6081 "noCalendar",
6082 "altInput",
6083 "shorthandCurrentMonth",
6084 "inline",
6085 "static",
6086 "enableSeconds",
6087 "disableMobile",
6088 ];
6089 var userConfig = __assign({}, instanceConfig, JSON.parse(JSON.stringify(element.dataset || {})));
6090 var formats = {};
6091 self.config.parseDate = userConfig.parseDate;
6092 self.config.formatDate = userConfig.formatDate;
6093 Object.defineProperty(self.config, "enable", {
6094 get: function () { return self.config._enable; },
6095 set: function (dates) {
6096 self.config._enable = parseDateRules(dates);
6097 }
6098 });
6099 Object.defineProperty(self.config, "disable", {
6100 get: function () { return self.config._disable; },
6101 set: function (dates) {
6102 self.config._disable = parseDateRules(dates);
6103 }
6104 });
6105 var timeMode = userConfig.mode === "time";
6106 if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {
6107 formats.dateFormat =
6108 userConfig.noCalendar || timeMode
6109 ? "H:i" + (userConfig.enableSeconds ? ":S" : "")
6110 : flatpickr.defaultConfig.dateFormat +
6111 " H:i" +
6112 (userConfig.enableSeconds ? ":S" : "");
6113 }
6114 if (userConfig.altInput &&
6115 (userConfig.enableTime || timeMode) &&
6116 !userConfig.altFormat) {
6117 formats.altFormat =
6118 userConfig.noCalendar || timeMode
6119 ? "h:i" + (userConfig.enableSeconds ? ":S K" : " K")
6120 : flatpickr.defaultConfig.altFormat +
6121 (" h:i" + (userConfig.enableSeconds ? ":S" : "") + " K");
6122 }
6123 Object.defineProperty(self.config, "minDate", {
6124 get: function () { return self.config._minDate; },
6125 set: minMaxDateSetter("min")
6126 });
6127 Object.defineProperty(self.config, "maxDate", {
6128 get: function () { return self.config._maxDate; },
6129 set: minMaxDateSetter("max")
6130 });
6131 var minMaxTimeSetter = function (type) { return function (val) {
6132 self.config[type === "min" ? "_minTime" : "_maxTime"] = self.parseDate(val, "H:i");
6133 }; };
6134 Object.defineProperty(self.config, "minTime", {
6135 get: function () { return self.config._minTime; },
6136 set: minMaxTimeSetter("min")
6137 });
6138 Object.defineProperty(self.config, "maxTime", {
6139 get: function () { return self.config._maxTime; },
6140 set: minMaxTimeSetter("max")
6141 });
6142 if (userConfig.mode === "time") {
6143 self.config.noCalendar = true;
6144 self.config.enableTime = true;
6145 }
6146 Object.assign(self.config, formats, userConfig);
6147 for (var i = 0; i < boolOpts.length; i++)
6148 self.config[boolOpts[i]] =
6149 self.config[boolOpts[i]] === true ||
6150 self.config[boolOpts[i]] === "true";
6151 HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {
6152 self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);
6153 });
6154 self.isMobile =
6155 !self.config.disableMobile &&
6156 !self.config.inline &&
6157 self.config.mode === "single" &&
6158 !self.config.disable.length &&
6159 !self.config.enable.length &&
6160 !self.config.weekNumbers &&
6161 /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
6162 for (var i = 0; i < self.config.plugins.length; i++) {
6163 var pluginConf = self.config.plugins[i](self) || {};
6164 for (var key in pluginConf) {
6165 if (HOOKS.indexOf(key) > -1) {
6166 self.config[key] = arrayify(pluginConf[key])
6167 .map(bindToInstance)
6168 .concat(self.config[key]);
6169 }
6170 else if (typeof userConfig[key] === "undefined")
6171 self.config[key] = pluginConf[key];
6172 }
6173 }
6174 triggerEvent("onParseConfig");
6175 }
6176 function setupLocale() {
6177 if (typeof self.config.locale !== "object" &&
6178 typeof flatpickr.l10ns[self.config.locale] === "undefined")
6179 self.config.errorHandler(new Error("flatpickr: invalid locale " + self.config.locale));
6180 self.l10n = __assign({}, flatpickr.l10ns["default"], (typeof self.config.locale === "object"
6181 ? self.config.locale
6182 : self.config.locale !== "default"
6183 ? flatpickr.l10ns[self.config.locale]
6184 : undefined));
6185 tokenRegex.K = "(" + self.l10n.amPM[0] + "|" + self.l10n.amPM[1] + "|" + self.l10n.amPM[0].toLowerCase() + "|" + self.l10n.amPM[1].toLowerCase() + ")";
6186 self.formatDate = createDateFormatter(self);
6187 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
6188 }
6189 function positionCalendar(customPositionElement) {
6190 if (self.calendarContainer === undefined)
6191 return;
6192 triggerEvent("onPreCalendarPosition");
6193 var positionElement = customPositionElement || self._positionElement;
6194 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" ||
6195 (configPosVertical !== "below" &&
6196 distanceFromBottom < calendarHeight &&
6197 inputBounds.top > calendarHeight);
6198 var top = window.pageYOffset +
6199 inputBounds.top +
6200 (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);
6201 toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
6202 toggleClass(self.calendarContainer, "arrowBottom", showOnTop);
6203 if (self.config.inline)
6204 return;
6205 var left = window.pageXOffset +
6206 inputBounds.left -
6207 (configPosHorizontal != null && configPosHorizontal === "center"
6208 ? (calendarWidth - inputBounds.width) / 2
6209 : 0);
6210 var right = window.document.body.offsetWidth - inputBounds.right;
6211 var rightMost = left + calendarWidth > window.document.body.offsetWidth;
6212 var centerMost = right + calendarWidth > window.document.body.offsetWidth;
6213 toggleClass(self.calendarContainer, "rightMost", rightMost);
6214 if (self.config.static)
6215 return;
6216 self.calendarContainer.style.top = top + "px";
6217 if (!rightMost) {
6218 self.calendarContainer.style.left = left + "px";
6219 self.calendarContainer.style.right = "auto";
6220 }
6221 else if (!centerMost) {
6222 self.calendarContainer.style.left = "auto";
6223 self.calendarContainer.style.right = right + "px";
6224 }
6225 else {
6226 var doc = document.styleSheets[0];
6227 // some testing environments don't have css support
6228 if (doc === undefined)
6229 return;
6230 var bodyWidth = window.document.body.offsetWidth;
6231 var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);
6232 var centerBefore = ".flatpickr-calendar.centerMost:before";
6233 var centerAfter = ".flatpickr-calendar.centerMost:after";
6234 var centerIndex = doc.cssRules.length;
6235 var centerStyle = "{left:" + inputBounds.left + "px;right:auto;}";
6236 toggleClass(self.calendarContainer, "rightMost", false);
6237 toggleClass(self.calendarContainer, "centerMost", true);
6238 doc.insertRule(centerBefore + "," + centerAfter + centerStyle, centerIndex);
6239 self.calendarContainer.style.left = centerLeft + "px";
6240 self.calendarContainer.style.right = "auto";
6241 }
6242 }
6243 function redraw() {
6244 if (self.config.noCalendar || self.isMobile)
6245 return;
6246 updateNavigationCurrentMonth();
6247 buildDays();
6248 }
6249 function focusAndClose() {
6250 self._input.focus();
6251 if (window.navigator.userAgent.indexOf("MSIE") !== -1 ||
6252 navigator.msMaxTouchPoints !== undefined) {
6253 // hack - bugs in the way IE handles focus keeps the calendar open
6254 setTimeout(self.close, 0);
6255 }
6256 else {
6257 self.close();
6258 }
6259 }
6260 function selectDate(e) {
6261 e.preventDefault();
6262 e.stopPropagation();
6263 var isSelectable = function (day) {
6264 return day.classList &&
6265 day.classList.contains("flatpickr-day") &&
6266 !day.classList.contains("disabled") &&
6267 !day.classList.contains("notAllowed");
6268 };
6269 var t = findParent(e.target, isSelectable);
6270 if (t === undefined)
6271 return;
6272 var target = t;
6273 var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));
6274 var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||
6275 selectedDate.getMonth() >
6276 self.currentMonth + self.config.showMonths - 1) &&
6277 self.config.mode !== "range";
6278 self.selectedDateElem = target;
6279 if (self.config.mode === "single")
6280 self.selectedDates = [selectedDate];
6281 else if (self.config.mode === "multiple") {
6282 var selectedIndex = isDateSelected(selectedDate);
6283 if (selectedIndex)
6284 self.selectedDates.splice(parseInt(selectedIndex), 1);
6285 else
6286 self.selectedDates.push(selectedDate);
6287 }
6288 else if (self.config.mode === "range") {
6289 if (self.selectedDates.length === 2) {
6290 self.clear(false, false);
6291 }
6292 self.latestSelectedDateObj = selectedDate;
6293 self.selectedDates.push(selectedDate);
6294 // unless selecting same date twice, sort ascendingly
6295 if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)
6296 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
6297 }
6298 setHoursFromInputs();
6299 if (shouldChangeMonth) {
6300 var isNewYear = self.currentYear !== selectedDate.getFullYear();
6301 self.currentYear = selectedDate.getFullYear();
6302 self.currentMonth = selectedDate.getMonth();
6303 if (isNewYear)
6304 triggerEvent("onYearChange");
6305 triggerEvent("onMonthChange");
6306 }
6307 updateNavigationCurrentMonth();
6308 buildDays();
6309 updateValue();
6310 if (self.config.enableTime)
6311 setTimeout(function () { return (self.showTimeInput = true); }, 50);
6312 // maintain focus
6313 if (!shouldChangeMonth &&
6314 self.config.mode !== "range" &&
6315 self.config.showMonths === 1)
6316 focusOnDayElem(target);
6317 else if (self.selectedDateElem !== undefined &&
6318 self.hourElement === undefined) {
6319 self.selectedDateElem && self.selectedDateElem.focus();
6320 }
6321 if (self.hourElement !== undefined)
6322 self.hourElement !== undefined && self.hourElement.focus();
6323 if (self.config.closeOnSelect) {
6324 var single = self.config.mode === "single" && !self.config.enableTime;
6325 var range = self.config.mode === "range" &&
6326 self.selectedDates.length === 2 &&
6327 !self.config.enableTime;
6328 if (single || range) {
6329 focusAndClose();
6330 }
6331 }
6332 triggerChange();
6333 }
6334 var CALLBACKS = {
6335 locale: [setupLocale, updateWeekdays],
6336 showMonths: [buildMonths, setCalendarWidth, buildWeekdays]
6337 };
6338 function set(option, value) {
6339 if (option !== null && typeof option === "object")
6340 Object.assign(self.config, option);
6341 else {
6342 self.config[option] = value;
6343 if (CALLBACKS[option] !== undefined)
6344 CALLBACKS[option].forEach(function (x) { return x(); });
6345 else if (HOOKS.indexOf(option) > -1)
6346 self.config[option] = arrayify(value);
6347 }
6348 self.redraw();
6349 updateValue(false);
6350 }
6351 function setSelectedDate(inputDate, format) {
6352 var dates = [];
6353 if (inputDate instanceof Array)
6354 dates = inputDate.map(function (d) { return self.parseDate(d, format); });
6355 else if (inputDate instanceof Date || typeof inputDate === "number")
6356 dates = [self.parseDate(inputDate, format)];
6357 else if (typeof inputDate === "string") {
6358 switch (self.config.mode) {
6359 case "single":
6360 case "time":
6361 dates = [self.parseDate(inputDate, format)];
6362 break;
6363 case "multiple":
6364 dates = inputDate
6365 .split(self.config.conjunction)
6366 .map(function (date) { return self.parseDate(date, format); });
6367 break;
6368 case "range":
6369 dates = inputDate
6370 .split(self.l10n.rangeSeparator)
6371 .map(function (date) { return self.parseDate(date, format); });
6372 break;
6373 default:
6374 break;
6375 }
6376 }
6377 else
6378 self.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(inputDate)));
6379 self.selectedDates = dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); });
6380 if (self.config.mode === "range")
6381 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
6382 }
6383 function setDate(date, triggerChange, format) {
6384 if (triggerChange === void 0) { triggerChange = false; }
6385 if (format === void 0) { format = self.config.dateFormat; }
6386 if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))
6387 return self.clear(triggerChange);
6388 setSelectedDate(date, format);
6389 self.showTimeInput = self.selectedDates.length > 0;
6390 self.latestSelectedDateObj = self.selectedDates[0];
6391 self.redraw();
6392 jumpToDate();
6393 setHoursFromDate();
6394 updateValue(triggerChange);
6395 if (triggerChange)
6396 triggerEvent("onChange");
6397 }
6398 function parseDateRules(arr) {
6399 return arr
6400 .slice()
6401 .map(function (rule) {
6402 if (typeof rule === "string" ||
6403 typeof rule === "number" ||
6404 rule instanceof Date) {
6405 return self.parseDate(rule, undefined, true);
6406 }
6407 else if (rule &&
6408 typeof rule === "object" &&
6409 rule.from &&
6410 rule.to)
6411 return {
6412 from: self.parseDate(rule.from, undefined),
6413 to: self.parseDate(rule.to, undefined)
6414 };
6415 return rule;
6416 })
6417 .filter(function (x) { return x; }); // remove falsy values
6418 }
6419 function setupDates() {
6420 self.selectedDates = [];
6421 self.now = self.parseDate(self.config.now) || new Date();
6422 // Workaround IE11 setting placeholder as the input's value
6423 var preloadedDate = self.config.defaultDate ||
6424 ((self.input.nodeName === "INPUT" ||
6425 self.input.nodeName === "TEXTAREA") &&
6426 self.input.placeholder &&
6427 self.input.value === self.input.placeholder
6428 ? null
6429 : self.input.value);
6430 if (preloadedDate)
6431 setSelectedDate(preloadedDate, self.config.dateFormat);
6432 self._initialDate =
6433 self.selectedDates.length > 0
6434 ? self.selectedDates[0]
6435 : self.config.minDate &&
6436 self.config.minDate.getTime() > self.now.getTime()
6437 ? self.config.minDate
6438 : self.config.maxDate &&
6439 self.config.maxDate.getTime() < self.now.getTime()
6440 ? self.config.maxDate
6441 : self.now;
6442 self.currentYear = self._initialDate.getFullYear();
6443 self.currentMonth = self._initialDate.getMonth();
6444 if (self.selectedDates.length > 0)
6445 self.latestSelectedDateObj = self.selectedDates[0];
6446 if (self.config.minTime !== undefined)
6447 self.config.minTime = self.parseDate(self.config.minTime, "H:i");
6448 if (self.config.maxTime !== undefined)
6449 self.config.maxTime = self.parseDate(self.config.maxTime, "H:i");
6450 self.minDateHasTime =
6451 !!self.config.minDate &&
6452 (self.config.minDate.getHours() > 0 ||
6453 self.config.minDate.getMinutes() > 0 ||
6454 self.config.minDate.getSeconds() > 0);
6455 self.maxDateHasTime =
6456 !!self.config.maxDate &&
6457 (self.config.maxDate.getHours() > 0 ||
6458 self.config.maxDate.getMinutes() > 0 ||
6459 self.config.maxDate.getSeconds() > 0);
6460 Object.defineProperty(self, "showTimeInput", {
6461 get: function () { return self._showTimeInput; },
6462 set: function (bool) {
6463 self._showTimeInput = bool;
6464 if (self.calendarContainer)
6465 toggleClass(self.calendarContainer, "showTimeInput", bool);
6466 self.isOpen && positionCalendar();
6467 }
6468 });
6469 }
6470 function setupInputs() {
6471 self.input = self.config.wrap
6472 ? element.querySelector("[data-input]")
6473 : element;
6474 /* istanbul ignore next */
6475 if (!self.input) {
6476 self.config.errorHandler(new Error("Invalid input element specified"));
6477 return;
6478 }
6479 // hack: store previous type to restore it after destroy()
6480 self.input._type = self.input.type;
6481 self.input.type = "text";
6482 self.input.classList.add("flatpickr-input");
6483 self._input = self.input;
6484 if (self.config.altInput) {
6485 // replicate self.element
6486 self.altInput = createElement(self.input.nodeName, self.input.className + " " + self.config.altInputClass);
6487 self._input = self.altInput;
6488 self.altInput.placeholder = self.input.placeholder;
6489 self.altInput.disabled = self.input.disabled;
6490 self.altInput.required = self.input.required;
6491 self.altInput.tabIndex = self.input.tabIndex;
6492 self.altInput.type = "text";
6493 self.input.setAttribute("type", "hidden");
6494 if (!self.config.static && self.input.parentNode)
6495 self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
6496 }
6497 if (!self.config.allowInput)
6498 self._input.setAttribute("readonly", "readonly");
6499 self._positionElement = self.config.positionElement || self._input;
6500 }
6501 function setupMobile() {
6502 var inputType = self.config.enableTime
6503 ? self.config.noCalendar
6504 ? "time"
6505 : "datetime-local"
6506 : "date";
6507 self.mobileInput = createElement("input", self.input.className + " flatpickr-mobile");
6508 self.mobileInput.step = self.input.getAttribute("step") || "any";
6509 self.mobileInput.tabIndex = 1;
6510 self.mobileInput.type = inputType;
6511 self.mobileInput.disabled = self.input.disabled;
6512 self.mobileInput.required = self.input.required;
6513 self.mobileInput.placeholder = self.input.placeholder;
6514 self.mobileFormatStr =
6515 inputType === "datetime-local"
6516 ? "Y-m-d\\TH:i:S"
6517 : inputType === "date"
6518 ? "Y-m-d"
6519 : "H:i:S";
6520 if (self.selectedDates.length > 0) {
6521 self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);
6522 }
6523 if (self.config.minDate)
6524 self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");
6525 if (self.config.maxDate)
6526 self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");
6527 self.input.type = "hidden";
6528 if (self.altInput !== undefined)
6529 self.altInput.type = "hidden";
6530 try {
6531 if (self.input.parentNode)
6532 self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
6533 }
6534 catch (_a) { }
6535 bind(self.mobileInput, "change", function (e) {
6536 self.setDate(e.target.value, false, self.mobileFormatStr);
6537 triggerEvent("onChange");
6538 triggerEvent("onClose");
6539 });
6540 }
6541 function toggle(e) {
6542 if (self.isOpen === true)
6543 return self.close();
6544 self.open(e);
6545 }
6546 function triggerEvent(event, data) {
6547 // If the instance has been destroyed already, all hooks have been removed
6548 if (self.config === undefined)
6549 return;
6550 var hooks = self.config[event];
6551 if (hooks !== undefined && hooks.length > 0) {
6552 for (var i = 0; hooks[i] && i < hooks.length; i++)
6553 hooks[i](self.selectedDates, self.input.value, self, data);
6554 }
6555 if (event === "onChange") {
6556 self.input.dispatchEvent(createEvent("change"));
6557 // many front-end frameworks bind to the input event
6558 self.input.dispatchEvent(createEvent("input"));
6559 }
6560 }
6561 function createEvent(name) {
6562 var e = document.createEvent("Event");
6563 e.initEvent(name, true, true);
6564 return e;
6565 }
6566 function isDateSelected(date) {
6567 for (var i = 0; i < self.selectedDates.length; i++) {
6568 if (compareDates(self.selectedDates[i], date) === 0)
6569 return "" + i;
6570 }
6571 return false;
6572 }
6573 function isDateInRange(date) {
6574 if (self.config.mode !== "range" || self.selectedDates.length < 2)
6575 return false;
6576 return (compareDates(date, self.selectedDates[0]) >= 0 &&
6577 compareDates(date, self.selectedDates[1]) <= 0);
6578 }
6579 function updateNavigationCurrentMonth() {
6580 if (self.config.noCalendar || self.isMobile || !self.monthNav)
6581 return;
6582 self.yearElements.forEach(function (yearElement, i) {
6583 var d = new Date(self.currentYear, self.currentMonth, 1);
6584 d.setMonth(self.currentMonth + i);
6585 self.monthElements[i].textContent =
6586 monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) +
6587 " ";
6588 yearElement.value = d.getFullYear().toString();
6589 });
6590 self._hidePrevMonthArrow =
6591 self.config.minDate !== undefined &&
6592 (self.currentYear === self.config.minDate.getFullYear()
6593 ? self.currentMonth <= self.config.minDate.getMonth()
6594 : self.currentYear < self.config.minDate.getFullYear());
6595 self._hideNextMonthArrow =
6596 self.config.maxDate !== undefined &&
6597 (self.currentYear === self.config.maxDate.getFullYear()
6598 ? self.currentMonth + 1 > self.config.maxDate.getMonth()
6599 : self.currentYear > self.config.maxDate.getFullYear());
6600 }
6601 function getDateStr(format) {
6602 return self.selectedDates
6603 .map(function (dObj) { return self.formatDate(dObj, format); })
6604 .filter(function (d, i, arr) {
6605 return self.config.mode !== "range" ||
6606 self.config.enableTime ||
6607 arr.indexOf(d) === i;
6608 })
6609 .join(self.config.mode !== "range"
6610 ? self.config.conjunction
6611 : self.l10n.rangeSeparator);
6612 }
6613 /**
6614 * Updates the values of inputs associated with the calendar
6615 */
6616 function updateValue(triggerChange) {
6617 if (triggerChange === void 0) { triggerChange = true; }
6618 if (self.selectedDates.length === 0)
6619 return self.clear(triggerChange);
6620 if (self.mobileInput !== undefined && self.mobileFormatStr) {
6621 self.mobileInput.value =
6622 self.latestSelectedDateObj !== undefined
6623 ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)
6624 : "";
6625 }
6626 self.input.value = getDateStr(self.config.dateFormat);
6627 if (self.altInput !== undefined) {
6628 self.altInput.value = getDateStr(self.config.altFormat);
6629 }
6630 if (triggerChange !== false)
6631 triggerEvent("onValueUpdate");
6632 }
6633 function onMonthNavClick(e) {
6634 e.preventDefault();
6635 var isPrevMonth = self.prevMonthNav.contains(e.target);
6636 var isNextMonth = self.nextMonthNav.contains(e.target);
6637 if (isPrevMonth || isNextMonth) {
6638 changeMonth(isPrevMonth ? -1 : 1);
6639 }
6640 else if (self.yearElements.indexOf(e.target) >= 0) {
6641 e.target.select();
6642 }
6643 else if (e.target.classList.contains("arrowUp")) {
6644 self.changeYear(self.currentYear + 1);
6645 }
6646 else if (e.target.classList.contains("arrowDown")) {
6647 self.changeYear(self.currentYear - 1);
6648 }
6649 }
6650 function timeWrapper(e) {
6651 e.preventDefault();
6652 var isKeyDown = e.type === "keydown", input = e.target;
6653 if (self.amPM !== undefined && e.target === self.amPM) {
6654 self.amPM.textContent =
6655 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
6656 }
6657 var min = parseFloat(input.getAttribute("min")), max = parseFloat(input.getAttribute("max")), step = parseFloat(input.getAttribute("step")), curValue = parseInt(input.value, 10), delta = e.delta ||
6658 (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);
6659 var newValue = curValue + step * delta;
6660 if (typeof input.value !== "undefined" && input.value.length === 2) {
6661 var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;
6662 if (newValue < min) {
6663 newValue =
6664 max +
6665 newValue +
6666 int(!isHourElem) +
6667 (int(isHourElem) && int(!self.amPM));
6668 if (isMinuteElem)
6669 incrementNumInput(undefined, -1, self.hourElement);
6670 }
6671 else if (newValue > max) {
6672 newValue =
6673 input === self.hourElement ? newValue - max - int(!self.amPM) : min;
6674 if (isMinuteElem)
6675 incrementNumInput(undefined, 1, self.hourElement);
6676 }
6677 if (self.amPM &&
6678 isHourElem &&
6679 (step === 1
6680 ? newValue + curValue === 23
6681 : Math.abs(newValue - curValue) > step)) {
6682 self.amPM.textContent =
6683 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
6684 }
6685 input.value = pad(newValue);
6686 }
6687 }
6688 init();
6689 return self;
6690 }
6691 /* istanbul ignore next */
6692 function _flatpickr(nodeList, config) {
6693 // static list
6694 var nodes = Array.prototype.slice
6695 .call(nodeList)
6696 .filter(function (x) { return x instanceof HTMLElement; });
6697 var instances = [];
6698 for (var i = 0; i < nodes.length; i++) {
6699 var node = nodes[i];
6700 try {
6701 if (node.getAttribute("data-fp-omit") !== null)
6702 continue;
6703 if (node._flatpickr !== undefined) {
6704 node._flatpickr.destroy();
6705 node._flatpickr = undefined;
6706 }
6707 node._flatpickr = FlatpickrInstance(node, config || {});
6708 instances.push(node._flatpickr);
6709 }
6710 catch (e) {
6711 console.error(e);
6712 }
6713 }
6714 return instances.length === 1 ? instances[0] : instances;
6715 }
6716 /* istanbul ignore next */
6717 if (typeof HTMLElement !== "undefined") {
6718 // browser env
6719 HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
6720 return _flatpickr(this, config);
6721 };
6722 HTMLElement.prototype.flatpickr = function (config) {
6723 return _flatpickr([this], config);
6724 };
6725 }
6726 /* istanbul ignore next */
6727 var flatpickr = function (selector, config) {
6728 if (typeof selector === "string") {
6729 return _flatpickr(window.document.querySelectorAll(selector), config);
6730 }
6731 else if (selector instanceof Node) {
6732 return _flatpickr([selector], config);
6733 }
6734 else {
6735 return _flatpickr(selector, config);
6736 }
6737 };
6738 /* istanbul ignore next */
6739 flatpickr.defaultConfig = defaults;
6740 flatpickr.l10ns = {
6741 en: __assign({}, english),
6742 "default": __assign({}, english)
6743 };
6744 flatpickr.localize = function (l10n) {
6745 flatpickr.l10ns["default"] = __assign({}, flatpickr.l10ns["default"], l10n);
6746 };
6747 flatpickr.setDefaults = function (config) {
6748 flatpickr.defaultConfig = __assign({}, flatpickr.defaultConfig, config);
6749 };
6750 flatpickr.parseDate = createDateParser({});
6751 flatpickr.formatDate = createDateFormatter({});
6752 flatpickr.compareDates = compareDates;
6753 /* istanbul ignore next */
6754 if (typeof jQuery !== "undefined") {
6755 jQuery.fn.flatpickr = function (config) {
6756 return _flatpickr(this, config);
6757 };
6758 }
6759 Date.prototype.fp_incr = function (days) {
6760 return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === "string" ? parseInt(days, 10) : days));
6761 };
6762 if (typeof window !== "undefined") {
6763 window.flatpickr = flatpickr;
6764 }
6765
6766 return flatpickr;
6767
6768 }));
6769 });
6770
6771 /* eslint no-underscore-dangle: [2, { "allow": ["_input", "_updateClassNames", "_updateInputFields"], "allowAfterThis": true }] */
6772 // `this.options` create-component mix-in creates prototype chain
6773 // so that `options` given in constructor argument wins over the one defined in static `options` property
6774 // 'Flatpickr' wants flat structure of object instead
6775
6776 function flattenOptions(options) {
6777 var o = {}; // eslint-disable-next-line guard-for-in, no-restricted-syntax
6778
6779 for (var key in options) {
6780 o[key] = options[key];
6781 }
6782
6783 return o;
6784 } // Weekdays shorthand for english locale
6785
6786
6787 flatpickr.l10ns.en.weekdays.shorthand.forEach(function (day, index) {
6788 var currentDay = flatpickr.l10ns.en.weekdays.shorthand;
6789
6790 if (currentDay[index] === 'Thu' || currentDay[index] === 'Th') {
6791 currentDay[index] = 'Th';
6792 } else {
6793 currentDay[index] = currentDay[index].charAt(0);
6794 }
6795 });
6796
6797 var toArray$6 = function toArray(arrayLike) {
6798 return Array.prototype.slice.call(arrayLike);
6799 };
6800
6801 var DatePicker =
6802 /*#__PURE__*/
6803 function (_mixin) {
6804 _inherits(DatePicker, _mixin);
6805
6806 /**
6807 * DatePicker.
6808 * @extends CreateComponent
6809 * @extends InitComponentBySearch
6810 * @extends Handles
6811 * @param {HTMLElement} element The element working as an date picker.
6812 */
6813 function DatePicker(element, options) {
6814 var _this;
6815
6816 _classCallCheck(this, DatePicker);
6817
6818 _this = _possibleConstructorReturn(this, _getPrototypeOf(DatePicker).call(this, element, options));
6819
6820 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocus", function () {
6821 if (_this.calendar) {
6822 _this.calendar.open();
6823 }
6824 });
6825
6826 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleBlur", function (event) {
6827 if (_this.calendar) {
6828 var focusTo = event.relatedTarget;
6829
6830 if (!focusTo || !_this.element.contains(focusTo) && (!_this.calendar.calendarContainer || !_this.calendar.calendarContainer.contains(focusTo))) {
6831 _this.calendar.close();
6832 }
6833 }
6834 });
6835
6836 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_initDatePicker", function (type) {
6837 if (type === 'range') {
6838 // Given FlatPickr assumes one `<input>` even in range mode,
6839 // use a hidden `<input>` for such purpose, separate from our from/to `<input>`s
6840 var doc = _this.element.ownerDocument;
6841 var rangeInput = doc.createElement('input');
6842 rangeInput.className = _this.options.classVisuallyHidden;
6843 rangeInput.setAttribute('aria-hidden', 'true');
6844
6845 _this.element.appendChild(rangeInput);
6846
6847 _this._rangeInput = rangeInput; // An attempt to open the date picker dropdown when this component gets focus,
6848 // and close the date picker dropdown when this component loses focus
6849
6850 var w = doc.defaultView;
6851 var hasFocusin = 'onfocusin' in w;
6852 var hasFocusout = 'onfocusout' in w;
6853 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
6854 var focusoutEventName = hasFocusout ? 'focusout' : 'blur';
6855
6856 _this.manage(on(_this.element, focusinEventName, _this._handleFocus, !hasFocusin));
6857
6858 _this.manage(on(_this.element, focusoutEventName, _this._handleBlur, !hasFocusout));
6859
6860 _this.manage(on(_this.element.querySelector(_this.options.selectorDatePickerIcon), focusoutEventName, _this._handleBlur, !hasFocusout));
6861 }
6862
6863 var self = _assertThisInitialized(_assertThisInitialized(_this));
6864
6865 var date = type === 'range' ? _this._rangeInput : _this.element.querySelector(_this.options.selectorDatePickerInput);
6866 var _this$options = _this.options,
6867 _onClose = _this$options.onClose,
6868 _onChange = _this$options.onChange,
6869 _onMonthChange = _this$options.onMonthChange,
6870 _onYearChange = _this$options.onYearChange,
6871 _onOpen = _this$options.onOpen,
6872 _onValueUpdate = _this$options.onValueUpdate;
6873 var calendar = new flatpickr(date, Object.assign(flattenOptions(_this.options), {
6874 allowInput: true,
6875 mode: type,
6876 positionElement: type === 'range' && _this.element.querySelector(_this.options.selectorDatePickerInputFrom),
6877 onClose: function onClose(selectedDates) {
6878 // An attempt to disable Flatpickr's focus tracking system,
6879 // which has adverse effect with our old set up with two `<input>`s or our latest setup with a hidden `<input>`
6880 if (self.shouldForceOpen) {
6881 if (self.calendar.calendarContainer) {
6882 self.calendar.calendarContainer.classList.add('open');
6883 }
6884
6885 self.calendar.isOpen = true;
6886 }
6887
6888 for (var _len = arguments.length, remainder = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6889 remainder[_key - 1] = arguments[_key];
6890 }
6891
6892 if (!_onClose || _onClose.call.apply(_onClose, [this, selectedDates].concat(remainder)) !== false) {
6893 self._updateClassNames(calendar);
6894
6895 self._updateInputFields(selectedDates, type);
6896 }
6897 },
6898 onChange: function onChange() {
6899 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
6900 args[_key2] = arguments[_key2];
6901 }
6902
6903 if (!_onChange || _onChange.call.apply(_onChange, [this].concat(args)) !== false) {
6904 self._updateClassNames(calendar);
6905
6906 if (type === 'range') {
6907 if (calendar.selectedDates.length === 1 && calendar.isOpen) {
6908 self.element.querySelector(self.options.selectorDatePickerInputTo).classList.add(self.options.classFocused);
6909 } else {
6910 self.element.querySelector(self.options.selectorDatePickerInputTo).classList.remove(self.options.classFocused);
6911 }
6912 }
6913 }
6914 },
6915 onMonthChange: function onMonthChange() {
6916 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
6917 args[_key3] = arguments[_key3];
6918 }
6919
6920 if (!_onMonthChange || _onMonthChange.call.apply(_onMonthChange, [this].concat(args)) !== false) {
6921 self._updateClassNames(calendar);
6922 }
6923 },
6924 onYearChange: function onYearChange() {
6925 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
6926 args[_key4] = arguments[_key4];
6927 }
6928
6929 if (!_onYearChange || _onYearChange.call.apply(_onYearChange, [this].concat(args)) !== false) {
6930 self._updateClassNames(calendar);
6931 }
6932 },
6933 onOpen: function onOpen() {
6934 // An attempt to disable Flatpickr's focus tracking system,
6935 // which has adverse effect with our old set up with two `<input>`s or our latest setup with a hidden `<input>`
6936 self.shouldForceOpen = true;
6937 setTimeout(function () {
6938 self.shouldForceOpen = false;
6939 }, 0);
6940
6941 for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
6942 args[_key5] = arguments[_key5];
6943 }
6944
6945 if (!_onOpen || _onOpen.call.apply(_onOpen, [this].concat(args)) !== false) {
6946 self._updateClassNames(calendar);
6947 }
6948 },
6949 onValueUpdate: function onValueUpdate() {
6950 for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
6951 args[_key6] = arguments[_key6];
6952 }
6953
6954 if ((!_onValueUpdate || _onValueUpdate.call.apply(_onValueUpdate, [this].concat(args)) !== false) && type === 'range') {
6955 self._updateInputFields(self.calendar.selectedDates, type);
6956 }
6957 },
6958 nextArrow: _this._rightArrowHTML(),
6959 prevArrow: _this._leftArrowHTML()
6960 }));
6961
6962 if (type === 'range') {
6963 _this._addInputLogic(_this.element.querySelector(_this.options.selectorDatePickerInputFrom), 0);
6964
6965 _this._addInputLogic(_this.element.querySelector(_this.options.selectorDatePickerInputTo), 1);
6966 }
6967
6968 _this.manage(on(_this.element.querySelector(_this.options.selectorDatePickerIcon), 'click', function () {
6969 calendar.open();
6970 }));
6971
6972 _this._updateClassNames(calendar);
6973
6974 if (type !== 'range') {
6975 _this._addInputLogic(date);
6976 }
6977
6978 return calendar;
6979 });
6980
6981 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_addInputLogic", function (input, index) {
6982 if (!isNaN(index) && (index < 0 || index > 1)) {
6983 throw new RangeError("The index of <input> (".concat(index, ") is out of range."));
6984 }
6985
6986 var inputField = input;
6987
6988 _this.manage(on(inputField, 'change', function (evt) {
6989 if (evt.isTrusted || evt.detail && evt.detail.isNotFromFlatpickr) {
6990 var inputDate = _this.calendar.parseDate(inputField.value);
6991
6992 if (inputDate && !isNaN(inputDate.valueOf())) {
6993 if (isNaN(index)) {
6994 _this.calendar.setDate(inputDate);
6995 } else {
6996 var selectedDates = _this.calendar.selectedDates;
6997 selectedDates[index] = inputDate;
6998
6999 _this.calendar.setDate(selectedDates);
7000 }
7001 }
7002 }
7003
7004 _this._updateClassNames(_this.calendar);
7005 })); // An attempt to temporarily set the `<input>` being edited as the one FlatPicker manages,
7006 // as FlatPicker attempts to take over `keydown` event handler on `document` to run on the date picker dropdown.
7007
7008
7009 _this.manage(on(inputField, 'keydown', function (evt) {
7010 var origInput = _this.calendar._input;
7011 _this.calendar._input = evt.target;
7012 setTimeout(function () {
7013 _this.calendar._input = origInput;
7014 });
7015 }));
7016 });
7017
7018 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_updateClassNames", function (_ref) {
7019 var calendarContainer = _ref.calendarContainer,
7020 selectedDates = _ref.selectedDates;
7021
7022 if (calendarContainer) {
7023 calendarContainer.classList.add(_this.options.classCalendarContainer);
7024 calendarContainer.querySelector('.flatpickr-month').classList.add(_this.options.classMonth);
7025 calendarContainer.querySelector('.flatpickr-weekdays').classList.add(_this.options.classWeekdays);
7026 calendarContainer.querySelector('.flatpickr-days').classList.add(_this.options.classDays);
7027 toArray$6(calendarContainer.querySelectorAll('.flatpickr-weekday')).forEach(function (item) {
7028 var currentItem = item;
7029 currentItem.innerHTML = currentItem.innerHTML.replace(/\s+/g, '');
7030 currentItem.classList.add(_this.options.classWeekday);
7031 });
7032 toArray$6(calendarContainer.querySelectorAll('.flatpickr-day')).forEach(function (item) {
7033 item.classList.add(_this.options.classDay);
7034
7035 if (item.classList.contains('today') && selectedDates.length > 0) {
7036 item.classList.add('no-border');
7037 } else if (item.classList.contains('today') && selectedDates.length === 0) {
7038 item.classList.remove('no-border');
7039 }
7040 });
7041 }
7042 });
7043
7044 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_updateInputFields", function (selectedDates, type) {
7045 if (type === 'range') {
7046 if (selectedDates.length === 2) {
7047 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).value = _this._formatDate(selectedDates[0]);
7048 _this.element.querySelector(_this.options.selectorDatePickerInputTo).value = _this._formatDate(selectedDates[1]);
7049 } else if (selectedDates.length === 1) {
7050 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).value = _this._formatDate(selectedDates[0]);
7051 }
7052 } else if (selectedDates.length === 1) {
7053 _this.element.querySelector(_this.options.selectorDatePickerInput).value = _this._formatDate(selectedDates[0]);
7054 }
7055
7056 _this._updateClassNames(_this.calendar);
7057 });
7058
7059 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_formatDate", function (date) {
7060 return _this.calendar.formatDate(date, _this.calendar.config.dateFormat);
7061 });
7062
7063 var _type = _this.element.getAttribute(_this.options.attribType);
7064
7065 _this.calendar = _this._initDatePicker(_type);
7066
7067 if (_this.calendar.calendarContainer) {
7068 _this.manage(on(_this.element, 'keydown', function (e) {
7069 if (e.which === 40) {
7070 _this.calendar.calendarContainer.focus();
7071 }
7072 }));
7073
7074 _this.manage(on(_this.calendar.calendarContainer, 'keydown', function (e) {
7075 if (e.which === 9 && _type === 'range') {
7076 _this._updateClassNames(_this.calendar);
7077
7078 _this.element.querySelector(_this.options.selectorDatePickerInputFrom).focus();
7079 }
7080 }));
7081 }
7082
7083 return _this;
7084 }
7085 /**
7086 * Opens the date picker dropdown when this component gets focus.
7087 * Used only for range mode for now.
7088 * @private
7089 */
7090
7091
7092 _createClass(DatePicker, [{
7093 key: "_rightArrowHTML",
7094 value: function _rightArrowHTML() {
7095 return "\n <svg width=\"8\" height=\"12\" viewBox=\"0 0 8 12\" fill-rule=\"evenodd\">\n <path d=\"M0 10.6L4.7 6 0 1.4 1.4 0l6.1 6-6.1 6z\"></path>\n </svg>";
7096 }
7097 }, {
7098 key: "_leftArrowHTML",
7099 value: function _leftArrowHTML() {
7100 return "\n <svg width=\"8\" height=\"12\" viewBox=\"0 0 8 12\" fill-rule=\"evenodd\">\n <path d=\"M7.5 10.6L2.8 6l4.7-4.6L6.1 0 0 6l6.1 6z\"></path>\n </svg>";
7101 }
7102 }, {
7103 key: "release",
7104 value: function release() {
7105 if (this._rangeInput && this._rangeInput.parentNode) {
7106 this._rangeInput.parentNode.removeChild(this._rangeInput);
7107 }
7108
7109 if (this.calendar) {
7110 try {
7111 this.calendar.destroy();
7112 } catch (err) {} // eslint-disable-line no-empty
7113
7114
7115 this.calendar = null;
7116 }
7117
7118 return _get(_getPrototypeOf(DatePicker.prototype), "release", this).call(this);
7119 }
7120 /**
7121 * The component options.
7122 * If `options` is specified in the constructor,
7123 * {@linkcode DatePicker.create .create()}, or {@linkcode DatePicker.init .init()},
7124 * properties in this object are overriden for the instance being create and how {@linkcode DatePicker.init .init()} works.
7125 * @property {string} selectorInit The CSS selector to find date picker UIs.
7126 */
7127
7128 }], [{
7129 key: "options",
7130 get: function get$$1() {
7131 var prefix = settings_1.prefix;
7132 return {
7133 selectorInit: '[data-date-picker]',
7134 selectorDatePickerInput: '[data-date-picker-input]',
7135 selectorDatePickerInputFrom: '[data-date-picker-input-from]',
7136 selectorDatePickerInputTo: '[data-date-picker-input-to]',
7137 selectorDatePickerIcon: '[data-date-picker-icon]',
7138 classCalendarContainer: "".concat(prefix, "--date-picker__calendar"),
7139 classMonth: "".concat(prefix, "--date-picker__month"),
7140 classWeekdays: "".concat(prefix, "--date-picker__weekdays"),
7141 classDays: "".concat(prefix, "--date-picker__days"),
7142 classWeekday: "".concat(prefix, "--date-picker__weekday"),
7143 classDay: "".concat(prefix, "--date-picker__day"),
7144 classFocused: "".concat(prefix, "--focused"),
7145 classVisuallyHidden: "".concat(prefix, "--visually-hidden"),
7146 attribType: 'data-date-picker-type',
7147 dateFormat: 'm/d/Y'
7148 };
7149 }
7150 /**
7151 * The map associating DOM element and date picker UI instance.
7152 * @type {WeakMap}
7153 */
7154
7155 }]);
7156
7157 return DatePicker;
7158 }(mixin(createComponent, initComponentBySearch, handles));
7159
7160 _defineProperty(DatePicker, "components",
7161 /* #__PURE_CLASS_PROPERTY__ */
7162 new WeakMap());
7163
7164 var toArray$7 = function toArray(arrayLike) {
7165 return Array.prototype.slice.call(arrayLike);
7166 };
7167
7168 var LeftNav =
7169 /*#__PURE__*/
7170 function (_mixin) {
7171 _inherits(LeftNav, _mixin);
7172
7173 /**
7174 * Left Navigation.
7175 * @extends CreateComponent
7176 * @extends InitComponentBySearch
7177 * @extends Handles
7178 * @param {HTMLElement} element The element working as a left navigation.
7179 * @param {Object} [options] The component options
7180 * @param {string} [options.selectorLeftNav] The data attribute selector for the nav element in the left nav container.
7181 * @param {string} [options.selectorLeftNavList] The data attribute selector for the main ul element in the left nav.
7182 * @param {string} [options.selectorLeftNavNestedList] The data attribute selector for the nested ul elements in the left nav.
7183 * @param {string} [options.selectorLeftNavToggle]
7184 * The data attribute selector for the button that will show and hide the left navigation.
7185 * @param {string} [options.selectorLeftNavListItem] The data attribute selector for all list items in the left navigation.
7186 * @param {string} [options.selectorLeftNavNestedListItem]
7187 * The data attribute selector for all nested list items in the left navigation.
7188 * @param {string} [options.selectorLeftNavArrowIcon] The data attribute selector for the arrow icons in the left nav.
7189 * @param {string} [options.selectorLeftNavFlyoutMenu] The data attribute selector for the flyout menus in the left nav.
7190 * @param {string} [options.selectorLeftNavFlyoutItem] The data attribute selector for the flyout menu items in the left nav.
7191 * @param {string} [options.selectorLeftNavSection]
7192 * The data attribute selector for the three sections in the header of the left nav.
7193 * @param {string} [options.selectorLeftNavCurrentPage]
7194 * The data attribute selector for the current section title in the left nav header.
7195 * @param {string} [options.selectorLeftNavMainNavHidden] The CSS selector for the hidden main nav.
7196 * @param {string} [options.classActiveLeftNav] The class name for when a left nav is active.
7197 * @param {string} [options.classActiveLeftNavListItem] The class name for when a left nav list item is active.
7198 * @param {string} [options.classExpandedLeftNavListItem] The class name for when a nested list is expanded.
7199 * @param {string} [options.classFlyoutDisplayed] The class name for when a flyout menu is displayed.
7200 * @param {string} [options.classActiveSection] The class name for an active section item in the left nav header.
7201 * @param {string} [options.classItemHasChildren] The class name for when a list item has children.
7202 * @param {string} [options.classTaxonomyIcon] The class name for the taxonomy icon.
7203 */
7204 function LeftNav(element, options) {
7205 var _this;
7206
7207 _classCallCheck(this, LeftNav);
7208
7209 _this = _possibleConstructorReturn(this, _getPrototypeOf(LeftNav).call(this, element, options));
7210
7211 _this.leftNavSectionActive = false;
7212
7213 _this.hookOpenActions();
7214
7215 _this.hookListSectionEvents();
7216
7217 _this.hookListItemsEvents();
7218
7219 _this.manage(on(_this.element.ownerDocument, 'click', function (evt) {
7220 _this.handleDocumentClick(evt);
7221 }));
7222
7223 return _this;
7224 }
7225 /**
7226 * Closes the menu.
7227 */
7228
7229
7230 _createClass(LeftNav, [{
7231 key: "closeMenu",
7232 value: function closeMenu() {
7233 this.element.classList.remove(this.options.classActiveLeftNav);
7234 var toggleOpenNode = this.element.ownerDocument.querySelector(this.options.selectorLeftNavToggleOpen);
7235 toggleOpenNode.classList.remove(this.options.classActiveTrigger);
7236 this.element.querySelector(this.options.selectorLeftNav).parentNode.setAttribute('aria-expanded', 'false');
7237 }
7238 /**
7239 * Toggles the menu to open and close.
7240 */
7241
7242 }, {
7243 key: "toggleMenu",
7244 value: function toggleMenu() {
7245 var leftNavContainer = this.element.querySelector(this.options.selectorLeftNav).parentNode;
7246 this.element.classList.toggle(this.options.classActiveLeftNav);
7247 var toggleOpenNode = this.element.ownerDocument.querySelector(this.options.selectorLeftNavToggleOpen);
7248 toggleOpenNode.classList.toggle(this.options.classActiveTrigger);
7249 if (leftNavContainer.getAttribute('aria-expanded') === 'false') leftNavContainer.setAttribute('aria-expanded', 'true');else leftNavContainer.setAttribute('aria-expanded', 'false');
7250 }
7251 /**
7252 * Adds a transitional animation to the navSection
7253 */
7254
7255 }, {
7256 key: "animateNavSection",
7257 value: function animateNavSection(selectedNav) {
7258 var _this2 = this;
7259
7260 var selectedNavValue = selectedNav.dataset.leftNavSection;
7261 var selectedNavLink = selectedNav.querySelector(this.options.selectorLeftNavSectionLink);
7262 var leftNav = this.element.querySelector(this.options.selectorLeftNav);
7263 var leftNavSections = this.element.querySelector(this.options.selectorLeftNavSections);
7264 selectedNav.classList.remove(this.options.classNavSection);
7265 selectedNav.classList.remove("".concat(this.options.classNavSection, "--").concat(selectedNavValue));
7266 selectedNav.classList.add(this.options.classNavSectionTransition);
7267
7268 if (leftNavSections.children[0] === selectedNav) {
7269 selectedNav.classList.add("".concat(this.options.classNavSectionTransition, "--50")); // First child only move 50px
7270 } else {
7271 selectedNav.classList.add("".concat(this.options.classNavSectionTransition, "--100")); // Second move 100px
7272 }
7273
7274 selectedNav.setAttribute('data-left-nav-section', selectedNavValue);
7275 /* Not sure what trick more performant */
7276
7277 setTimeout(function () {
7278 selectedNav.classList.add("".concat(_this2.options.classNavSectionTransition, "--0"));
7279 }, 100); // Could probably use a promise here
7280
7281 selectedNavLink.classList.remove(this.options.classNavSectionLink);
7282 selectedNavLink.classList.add(this.options.classNavHeaderTitle);
7283 selectedNavLink.setAttribute('data-left-nav-current-section-title', '');
7284 selectedNavLink.removeAttribute('data-left-nav-section-link');
7285 this.element.insertBefore(selectedNav, leftNav);
7286 }
7287 /**
7288 * Adds a transitional animation to the navigation items on nav section click
7289 */
7290
7291 }, {
7292 key: "animateNavList",
7293 value: function animateNavList(selectedNavTitle) {
7294 var _this3 = this;
7295
7296 var currentLeftNavList = this.element.querySelector("".concat(this.options.selectorLeftNavList, ":not(").concat(this.options.selectorLeftNavMainNavHidden, ")"));
7297 var newLeftNavList = this.element.querySelector("[data-left-nav-list=".concat(selectedNavTitle, "]"));
7298 var currentLeftNavItems = toArray$7(currentLeftNavList.querySelectorAll(this.options.selectorLeftNavListItem)).reverse();
7299 var newLeftNavItems = toArray$7(newLeftNavList.querySelectorAll(this.options.selectorLeftNavListItem));
7300 var fadeOutTime = 300;
7301 var counter = 0;
7302 var counterIteration = fadeOutTime / currentLeftNavItems.length; // Length of animation divided by number of items
7303
7304 currentLeftNavItems.forEach(function (item) {
7305 item.setAttribute('tabIndex', '-1');
7306 setTimeout(function () {
7307 item.classList.add(_this3.options.classItemFade);
7308 }, counter);
7309 counter += counterIteration;
7310 });
7311 newLeftNavItems.forEach(function (item) {
7312 item.setAttribute('tabIndex', '0');
7313 item.classList.remove(_this3.options.classItemFade);
7314 });
7315 setTimeout(function () {
7316 currentLeftNavList.classList.add(_this3.options.classListHidden);
7317 currentLeftNavList.classList.add(_this3.options.classListTop);
7318 currentLeftNavList.setAttribute('aria-hidden', 'true');
7319 newLeftNavList.classList.remove(_this3.options.classListHidden);
7320 setTimeout(function () {
7321 newLeftNavList.classList.remove(_this3.options.classListTop);
7322 }, 100);
7323 newLeftNavList.setAttribute('aria-hidden', 'false');
7324 }, fadeOutTime + 100); // Wait for items to fade out.
7325 }
7326 }, {
7327 key: "hookOpenActions",
7328 value: function hookOpenActions() {
7329 var _this4 = this;
7330
7331 var openBtn = this.element.ownerDocument.querySelector(this.options.selectorLeftNavToggleOpen);
7332 var closeBtn = this.element.ownerDocument.querySelector(this.options.selectorLeftNavToggleClose);
7333 this.manage(on(openBtn, 'click', function () {
7334 _this4.element.tabIndex = '0';
7335
7336 _this4.toggleMenu();
7337 }));
7338 this.manage(on(openBtn, 'keydown', function (evt) {
7339 if (evt.which === 13) {
7340 _this4.element.tabIndex = '0';
7341
7342 _this4.toggleMenu();
7343 }
7344 }));
7345
7346 if (closeBtn) {
7347 this.manage(on(closeBtn, 'click', function () {
7348 _this4.element.tabIndex = '-1';
7349
7350 _this4.closeMenu();
7351 }));
7352 this.manage(on(closeBtn, 'keydown', function (evt) {
7353 if (evt.which === 13) {
7354 _this4.element.tabIndex = '-1';
7355
7356 _this4.closeMenu();
7357 }
7358 }));
7359 }
7360
7361 this.manage(on(this.element.ownerDocument, 'keydown', function (evt) {
7362 if (evt.which === 27 && _this4.element.classList.contains(_this4.options.classActiveLeftNav)) {
7363 _this4.closeMenu();
7364 }
7365 }));
7366 }
7367 /**
7368 * Addes Event listeners to list sections
7369 */
7370
7371 }, {
7372 key: "hookListSectionEvents",
7373 value: function hookListSectionEvents() {
7374 var _this5 = this;
7375
7376 var leftNavSections = this.element.querySelector(this.options.selectorLeftNavSections);
7377 this.manage(on(leftNavSections, 'click', function (evt) {
7378 _this5.handleSectionItemClick(evt, leftNavSections);
7379 }));
7380 this.manage(on(leftNavSections, 'keydown', function (evt) {
7381 if (evt.which === 13) {
7382 _this5.handleSectionItemClick(evt, leftNavSections);
7383
7384 _this5.element.querySelector(_this5.options.selectorLeftNavCurrentSectionTitle).focus();
7385 }
7386 }));
7387 }
7388 /**
7389 * Adds event listeners to list items
7390 */
7391
7392 }, {
7393 key: "hookListItemsEvents",
7394 value: function hookListItemsEvents() {
7395 var _this6 = this;
7396
7397 var leftNavList = toArray$7(this.element.querySelectorAll(this.options.selectorLeftNavList));
7398 leftNavList.forEach(function (list) {
7399 _this6.manage(on(list, 'click', function (evt) {
7400 var leftNavItem = eventMatches(evt, _this6.options.selectorLeftNavListItem);
7401
7402 if (leftNavItem) {
7403 var childItem = eventMatches(evt, _this6.options.selectorLeftNavNestedListItem);
7404 var hasChildren = eventMatches(evt, _this6.options.selectorLeftNavListItemHasChildren);
7405 var flyoutItem = eventMatches(evt, _this6.options.selectorLeftNavFlyoutItem);
7406
7407 if (flyoutItem) {
7408 _this6.addActiveListItem(flyoutItem);
7409 } else if (childItem) {
7410 if (childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu)) {
7411 var flyoutMenu = childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu);
7412 flyoutMenu.classList.toggle(_this6.options.classFlyoutDisplayed);
7413 } else {
7414 _this6.addActiveListItem(childItem);
7415 }
7416 } else if (hasChildren) {
7417 _this6.handleNestedListClick(leftNavItem);
7418 } else {
7419 _this6.addActiveListItem(leftNavItem);
7420 }
7421 }
7422 }));
7423
7424 _this6.manage(on(list, 'keydown', function (evt) {
7425 if (evt.which === 13) {
7426 var leftNavItem = eventMatches(evt, _this6.options.selectorLeftNavListItem);
7427
7428 if (leftNavItem) {
7429 var childItem = eventMatches(evt, _this6.options.selectorLeftNavNestedListItem);
7430 var hasChildren = eventMatches(evt, _this6.options.selectorLeftNavListItemHasChildren);
7431 var flyoutItem = eventMatches(evt, _this6.options.selectorLeftNavFlyoutItem);
7432 var hasLinkItem = !(leftNavItem.querySelector(_this6.options.selectorLeftNavListItemLink) === undefined);
7433
7434 if (flyoutItem) {
7435 _this6.addActiveListItem(flyoutItem);
7436 } else if (childItem) {
7437 if (!childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu)) {
7438 _this6.addActiveListItem(childItem);
7439 } else {
7440 childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu).setAttribute('aria-hidden', 'false');
7441 childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu).style.top = "".concat(childItem.offsetTop - _this6.element.querySelector(_this6.options.selectorLeftNav).scrollTop, "px");
7442 childItem.querySelector(_this6.options.selectorLeftNavFlyoutMenu).style.left = "".concat(childItem.offsetLeft + Math.round(childItem.offsetWidth), "px");
7443 }
7444 } else if (hasChildren) {
7445 _this6.handleNestedListClick(leftNavItem);
7446 } else if (hasLinkItem) {
7447 var link = leftNavItem.querySelector(_this6.options.selectorLeftNavListItemLink);
7448 link.click();
7449 } else {
7450 _this6.addActiveListItem(leftNavItem);
7451 }
7452 }
7453 }
7454 }));
7455 });
7456 var flyouts = toArray$7(this.element.ownerDocument.querySelectorAll(this.options.selectorLeftNavListItemHasFlyout));
7457 flyouts.forEach(function (flyout) {
7458 _this6.manage(on(flyout, 'mouseenter', function () {
7459 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).setAttribute('aria-hidden', 'false'); // eslint-disable-next-line no-param-reassign
7460
7461 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).style.top = "".concat(flyout.offsetTop - _this6.element.querySelector(_this6.options.selectorLeftNav).scrollTop, "px"); // eslint-disable-next-line no-param-reassign
7462
7463 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).style.left = "".concat(flyout.offsetLeft + Math.round(flyout.offsetWidth), "px");
7464 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).classList.toggle(_this6.options.classFlyoutDisplayed);
7465 }));
7466
7467 _this6.manage(on(flyout, 'mouseleave', function () {
7468 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).setAttribute('aria-hidden', 'true');
7469 flyout.querySelector(_this6.options.selectorLeftNavFlyoutMenu).classList.remove(_this6.options.classFlyoutDisplayed);
7470 }));
7471 });
7472 }
7473 /**
7474 * Hides all flyout menus.
7475 */
7476
7477 }, {
7478 key: "hideAllFlyoutMenus",
7479 value: function hideAllFlyoutMenus() {
7480 var _this7 = this;
7481
7482 var flyoutMenus = toArray$7(this.element.querySelectorAll(this.options.selectorLeftNavFlyoutMenu));
7483 flyoutMenus.forEach(function (menu) {
7484 menu.setAttribute('aria-hidden', 'true');
7485 menu.classList.remove(_this7.options.classFlyoutDisplayed);
7486 });
7487 }
7488 /**
7489 * Sets a list item as active.
7490 * @param {Object} item The active list item.
7491 */
7492
7493 }, {
7494 key: "addActiveListItem",
7495 value: function addActiveListItem(item) {
7496 var _this8 = this;
7497
7498 toArray$7(this.element.querySelectorAll(this.options.selectorLeftNavAllListItems)).forEach(function (currentItem) {
7499 if (!(item === currentItem)) {
7500 if (!currentItem.contains(item)) {
7501 currentItem.classList.remove(_this8.options.classActiveLeftNavListItem);
7502 } else {
7503 currentItem.classList.add(_this8.options.classActiveLeftNavListItem);
7504 }
7505 }
7506 });
7507 toArray$7(this.element.querySelectorAll(this.options.selectorLeftNavNestedListItem)).forEach(function (currentItem) {
7508 if (!(item === currentItem)) {
7509 currentItem.classList.remove(_this8.options.classActiveLeftNavListItem);
7510 }
7511 });
7512 item.classList.add(this.options.classActiveLeftNavListItem);
7513 this.closeMenu();
7514 this.hideAllFlyoutMenus();
7515 this.closeMenu();
7516 }
7517 /**
7518 * Handles click on the document.
7519 * Closes the left navigation when document is clicked outside the left navigation.
7520 * @param {Event} evt The event triggering this method.
7521 */
7522
7523 }, {
7524 key: "handleDocumentClick",
7525 value: function handleDocumentClick(evt) {
7526 var clickTarget = evt.target;
7527 var isOfSelf = this.element.contains(clickTarget);
7528 var isToggleBtn = this.element.ownerDocument.querySelector(this.options.selectorLeftNavToggleOpen).contains(clickTarget);
7529 var isOpen = this.element.classList.contains(this.options.classActiveLeftNav);
7530 var isUnifiedHeader = this.element.ownerDocument.querySelector('[data-unified-header]').contains(clickTarget);
7531 var shouldClose = !isOfSelf && isOpen && !isToggleBtn && !isUnifiedHeader;
7532 var flyoutOpen;
7533
7534 if (this.element.querySelector(this.options.selectorLeftNavFlyoutMenu)) {
7535 var leftnavFlyoutMenu = this.element.querySelector(this.options.selectorLeftNavFlyoutMenu);
7536 flyoutOpen = leftnavFlyoutMenu.classList.contains(this.options.classFlyoutDisplayed);
7537 }
7538
7539 if (isOfSelf && this.element.tagName === 'A') {
7540 evt.preventDefault();
7541 }
7542
7543 if (shouldClose) {
7544 this.closeMenu();
7545 }
7546
7547 if (this.element.querySelector(this.options.selectorLeftNavFlyoutMenu)) {
7548 if (flyoutOpen && !isOfSelf && isOpen) {
7549 this.element.querySelector(this.options.selectorLeftNavFlyoutMenu).classList.remove(this.options.classFlyoutDisplayed);
7550 }
7551 }
7552 }
7553 /**
7554 * Handles click on a list item that contains a nested list in the left navigation.
7555 * It hides all flyout menus and switches the tab-index on the list items based on whether or not the list is expanded.
7556 * @param {HTMLElement} listItem The list item that was clicked.
7557 */
7558
7559 }, {
7560 key: "handleNestedListClick",
7561 value: function handleNestedListClick(listItem) {
7562 var _this9 = this;
7563
7564 var isOpen = listItem.classList.contains(this.options.classExpandedLeftNavListItem);
7565 this.hideAllFlyoutMenus();
7566 listItem.classList.toggle(this.options.classExpandedLeftNavListItem, !isOpen);
7567 var listItems = toArray$7(listItem.querySelectorAll(this.options.selectorLeftNavNestedListItem));
7568 listItems.forEach(function (item) {
7569 if (isOpen) {
7570 listItem.querySelector(_this9.options.selectorLeftNavNestedList).setAttribute('aria-hidden', 'true'); // eslint-disable-next-line no-param-reassign
7571
7572 item.querySelector(_this9.options.selectorLeftNavListItemLink).tabIndex = -1;
7573 } else {
7574 listItem.querySelector(_this9.options.selectorLeftNavNestedList).setAttribute('aria-hidden', 'false'); // eslint-disable-next-line no-param-reassign
7575
7576 item.querySelector(_this9.options.selectorLeftNavListItemLink).tabIndex = 0;
7577 }
7578 });
7579 }
7580 }, {
7581 key: "handleSectionItemClick",
7582 value: function handleSectionItemClick(evt, leftNavSections) {
7583 var _this10 = this;
7584
7585 // Sorry
7586 var leftNavSectionItem = eventMatches(evt, this.options.selectorLeftNavSection);
7587
7588 if (leftNavSectionItem) {
7589 // currently selected
7590 var selectedLeftNavSectionItem = this.element.querySelector(this.options.selectorLeftNavCurrentSection);
7591 var selectedLeftNavSectionItemTitle = selectedLeftNavSectionItem.querySelector(this.options.selectorLeftNavCurrentSectionTitle);
7592 var selectedLeftNavSectionItemIcon = this.element.querySelector(this.options.selectorLeftNavCurrentSectionIcon);
7593 var selectedLeftNavSectionItemUse = selectedLeftNavSectionItemIcon.querySelector('use');
7594 var selectedLeftNavSectionValue = selectedLeftNavSectionItem.dataset.leftNavCurrentSection; // clicked on item
7595
7596 var leftNavSectionItemLink = leftNavSectionItem.querySelector(this.options.selectorLeftNavSectionLink);
7597 var leftNavSectionItemIcon = leftNavSectionItem.querySelector(this.options.selectorLeftNavSectionIcon);
7598 var leftNavSectionItemIconUse = leftNavSectionItemIcon.querySelector('use');
7599 var leftNavSectionValue = leftNavSectionItem.dataset.leftNavSection;
7600
7601 if (this.leftNavSectionActive) {
7602 return;
7603 }
7604
7605 this.leftNavSectionActive = true;
7606 var newLeftNavSectionItem = document.createElement('li');
7607 newLeftNavSectionItem.setAttribute('data-left-nav-section', selectedLeftNavSectionValue);
7608 newLeftNavSectionItem.classList.add(this.options.classNavSection);
7609 newLeftNavSectionItem.classList.add("".concat(this.options.classNavSection, "--").concat(selectedLeftNavSectionValue));
7610 var newLeftNavSectionItemAnchor = document.createElement('a');
7611 newLeftNavSectionItemAnchor.setAttribute('href', 'javascript:void(0)'); // eslint-disable-line no-script-url
7612
7613 newLeftNavSectionItemAnchor.setAttribute('tabindex', 0);
7614 newLeftNavSectionItemAnchor.classList.add(this.options.classNavSectionAnchor);
7615 var newLeftNavSectionItemIcon = selectedLeftNavSectionItemIcon.cloneNode(true); // IE11 doesn't support classList on SVG, must revert to className
7616
7617 newLeftNavSectionItemIcon.setAttribute('class', this.options.classTaxonomyIcon);
7618 newLeftNavSectionItemIcon.removeAttribute('data-left-nav-current-section-icon');
7619 newLeftNavSectionItemIcon.setAttribute('data-left-nav-section-icon', selectedLeftNavSectionValue);
7620 var newLeftNavSectionItemLink = document.createElement('span');
7621 newLeftNavSectionItemLink.setAttribute('data-left-nav-section-link', '');
7622 newLeftNavSectionItemLink.classList.add(this.options.classNavSectionLink);
7623 newLeftNavSectionItemLink.textContent = selectedLeftNavSectionItemTitle.textContent;
7624 this.animateNavSection(leftNavSectionItem);
7625 this.animateNavList(leftNavSectionValue);
7626 newLeftNavSectionItemAnchor.appendChild(newLeftNavSectionItemIcon);
7627 newLeftNavSectionItemAnchor.appendChild(newLeftNavSectionItemLink);
7628 newLeftNavSectionItem.appendChild(newLeftNavSectionItemAnchor);
7629 leftNavSections.insertBefore(newLeftNavSectionItem, leftNavSections.firstChild);
7630 setTimeout(function () {
7631 selectedLeftNavSectionItemTitle.textContent = leftNavSectionItemLink.textContent;
7632 selectedLeftNavSectionItem.setAttribute('data-left-nav-current-section', leftNavSectionValue);
7633 selectedLeftNavSectionItemIcon.setAttribute('data-left-nav-current-section-icon', leftNavSectionValue);
7634 selectedLeftNavSectionItemUse.setAttribute('xlink:href', leftNavSectionItemIconUse.getAttribute('xlink:href'));
7635 leftNavSectionItem.parentNode.removeChild(leftNavSectionItem); // Cant use .remove() because of IE11
7636
7637 _this10.leftNavSectionActive = false;
7638 }, 450); // Wait for nav items to animate
7639 }
7640 }
7641 /**
7642 * The component options.
7643 * If `options` is specified in the constructor, {@linkcode LeftNav.create .create()}, or {@linkcode LeftNav.init .init()},
7644 * properties in this object are overriden for the instance being create and how {@linkcode LeftNav.init .init()} works.
7645 * @member LeftNav.options
7646 * @type {Object}
7647 * @property {string} selectorInit The CSS selector to find left nav containers.
7648 * @property {string} [selectorLeftNav] The data attribute selector for the nav element in the left nav container.
7649 * @property {string} [selectorLeftNavList] The data attribute selector for the main ul element in the left nav.
7650 * @property {string} [selectorLeftNavNestedList] The data attribute selector for the nested ul elements in the left nav.
7651 * @property {string} [selectorLeftNavToggle]
7652 * The data attribute selector for the button that will show and hide the left navigation.
7653 * @property {string} [selectorLeftNavListItem] The data attribute selector for all list items in the left navigation.
7654 * @property {string} [selectorLeftNavNestedListItem]
7655 * The data attribute selector for all nested list items in the left navigation.
7656 * @property {string} [selectorLeftNavArrowIcon] The data attribute selector for the arrow icons in the left nav.
7657 * @property {string} [selectorLeftNavFlyoutMenu] The data attribute selector for the flyout menus in the left nav.
7658 * @property {string} [selectorLeftNavFlyoutItem] The data attribute selector for the flyout menu items in the left nav.
7659 * @property {string} [selectorLeftNavSection] The data attribute selector for the three sections in the header of the left nav.
7660 * @property {string} [selectorLeftNavCurrentPage]
7661 * The data attribute selector for the current section title in the left nav header.
7662 * @property {string} [selectorLeftNavMainNavHidden] The CSS selector for the hidden main nav.
7663 * @property {string} [classActiveLeftNav] The class name for when a left nav is active.
7664 * @property {string} [classActiveLeftNavListItem] The class name for when a left nav list item is active.
7665 * @property {string} [classExpandedLeftNavListItem] The class name for when a nested list is expanded.
7666 * @property {string} [classFlyoutDisplayed] The class name for when a flyout menu is displayed.
7667 * @property {string} [classActiveSection] The class name for an active section item in the left nav header.
7668 * @property {string} [classItemHasChildren] The class name for when a list item has children.
7669 * @property {string} [classTaxonomyIcon] The class name for the taxonomy icon.
7670 */
7671
7672 }], [{
7673 key: "options",
7674 get: function get() {
7675 var prefix = settings_1.prefix;
7676 return {
7677 selectorInit: '[data-left-nav-container]',
7678 // Data Attribute selectors
7679 selectorLeftNav: '[data-left-nav]',
7680 selectorLeftNavList: '[data-left-nav-list]',
7681 selectorLeftNavNestedList: '[data-left-nav-nested-list]',
7682 selectorLeftNavToggleOpen: '[data-left-nav-toggle="open"]',
7683 selectorLeftNavToggleClose: '[data-left-nav-toggle="close"]',
7684 selectorLeftNavListItem: '[data-left-nav-item]',
7685 selectorLeftNavListItemLink: '[data-left-nav-item-link]',
7686 selectorLeftNavNestedListItem: '[data-left-nav-nested-item]',
7687 selectorLeftNavArrowIcon: '[data-left-nav-icon]',
7688 selectorLeftNavFlyoutMenu: '[data-left-nav-flyout]',
7689 selectorLeftNavFlyoutItem: '[data-left-nav-flyout-item]',
7690 selectorLeftNavSections: '[data-left-nav-sections]',
7691 selectorLeftNavSection: '[data-left-nav-section]',
7692 selectorLeftNavSectionLink: '[data-left-nav-section-link]',
7693 selectorLeftNavSectionIcon: '[data-left-nav-section-icon]',
7694 selectorLeftNavCurrentSection: '[data-left-nav-current-section]',
7695 selectorLeftNavCurrentSectionTitle: '[data-left-nav-current-section-title]',
7696 selectorLeftNavCurrentSectionIcon: '[data-left-nav-current-section-icon]',
7697 selectorLeftNavListItemHasChildren: '[data-left-nav-item-with-children]',
7698 selectorLeftNavListItemHasFlyout: '[data-left-nav-has-flyout]',
7699 selectorLeftNavAllListItems: '[data-left-nav-item], [data-left-nav-nested-item], [data-left-nav-flyout-item]',
7700 selectorLeftNavMainNavHidden: ".".concat(prefix, "--left-nav__main-nav--hidden"),
7701 // CSS Class Selectors
7702 classActiveTrigger: "".concat(prefix, "--left-nav__trigger--active"),
7703 classActiveLeftNav: "".concat(prefix, "--left-nav--active"),
7704 classActiveLeftNavListItem: "".concat(prefix, "--active-list-item"),
7705 classExpandedLeftNavListItem: "".concat(prefix, "--main-nav__parent-item--expanded"),
7706 classFlyoutDisplayed: "".concat(prefix, "--nested-list__flyout-menu--displayed"),
7707 classItemHasChildren: "".concat(prefix, "--main-nav__parent-item--has-children"),
7708 classNavSection: "".concat(prefix, "--left-nav__section"),
7709 classNavSectionTransition: "".concat(prefix, "--left-nav__section--transition"),
7710 classNavSectionAnchor: "".concat(prefix, "--left-nav__section--anchor"),
7711 classNavSectionLink: "".concat(prefix, "--left-nav__section--link"),
7712 classNavHeaderTitle: "".concat(prefix, "--left-nav__header--title"),
7713 classItemFade: "".concat(prefix, "--main-nav__parent-item--fade"),
7714 classItemHidden: "".concat(prefix, "--main-nav__parent-item--hidden"),
7715 classListHidden: "".concat(prefix, "--left-nav__main-nav--hidden"),
7716 classListTop: "".concat(prefix, "--left-nav__main-nav--top"),
7717 classTaxonomyIcon: "".concat(prefix, "--left-nav__section--taxonomy-icon")
7718 };
7719 }
7720 /**
7721 * The map associating DOM element and left navigation instance.
7722 * @member LeftNav.components
7723 * @type {WeakMap}
7724 */
7725
7726 }]);
7727
7728 return LeftNav;
7729 }(mixin(createComponent, initComponentBySearch, handles));
7730
7731 _defineProperty(LeftNav, "components",
7732 /* #__PURE_CLASS_PROPERTY__ */
7733 new WeakMap());
7734
7735 var leftNav = !breakingChangesX ? LeftNav : removedComponent('LeftNav');
7736
7737 var ProfileSwitcher =
7738 /*#__PURE__*/
7739 function (_mixin) {
7740 _inherits(ProfileSwitcher, _mixin);
7741
7742 /**
7743 * Profile Switcher.
7744 * @extends CreateComponent
7745 * @extends InitComponentBySearch
7746 * @extends Handles
7747 * @param {HTMLElement} element The element working as a profile switcher.
7748 * @param {Object} [options] The component options
7749 * @param {string} [options.selectorProfileSwitcher] The data attribute selector for the profile switcher.
7750 * @param {string} [options.selectorAccount]
7751 * The data attribute selector for the element containing the account name in the profile switcher.
7752 * @param {string} [options.selectorOrg]
7753 * The data attribute selector for the element containing the organization name in the profile switcher.
7754 * @param {string} [options.selectorSpace]
7755 * The data attribute selector for the element containing the space name in the profile switcher.
7756 * @param {string} [options.selectorAccountDropdown]
7757 * The data attribute selector for the dropdown item containing the current account name.
7758 * @param {string} [options.selectorOrgDropdown]
7759 * The data attribute selector for the dropdown item containing the current organization name.
7760 * @param {string} [options.selectorSpaceDropdown]
7761 * The data attribute selector for the dropdown item containing the current space name.
7762 */
7763 function ProfileSwitcher(element, options) {
7764 var _this;
7765
7766 _classCallCheck(this, ProfileSwitcher);
7767
7768 _this = _possibleConstructorReturn(this, _getPrototypeOf(ProfileSwitcher).call(this, element, options));
7769
7770 _this.manage(on(_this.element.ownerDocument, 'click', function (evt) {
7771 _this.handleDocumentClick(evt);
7772 }));
7773
7774 _this.manage(on(_this.element, 'dropdown-beingselected', function (event) {
7775 if (event.target.querySelector(_this.options.selectorAccountDropdown) !== null) {
7776 var linkedIconNode = event.detail.item.querySelector(_this.options.classLinkedIcon);
7777 _this.element.isLinked = !!linkedIconNode;
7778 _this.element.linkedIcon = linkedIconNode && linkedIconNode.cloneNode(true);
7779 var linkedAccountNode = event.detail.item.querySelector(_this.options.selectorAccountSlLinked);
7780 _this.element.linkedAccount = linkedAccountNode && linkedAccountNode.cloneNode(true);
7781 }
7782 }));
7783
7784 var toggleNode = _this.element.querySelector(_this.options.selectorToggle);
7785
7786 if (toggleNode) {
7787 _this.manage(on(toggleNode, 'keydown', function (event) {
7788 _this.toggle(event);
7789 }));
7790
7791 _this.manage(on(toggleNode, 'mouseenter', function (event) {
7792 _this.getLinkedData(event);
7793
7794 _this.determineSwitcherValues(true);
7795 }));
7796
7797 _this.manage(on(toggleNode, 'mouseleave', function (event) {
7798 _this.getLinkedData(event);
7799
7800 _this.determineSwitcherValues(false);
7801 }));
7802 }
7803
7804 _this.manage(on(_this.element.ownerDocument, 'keyup', function () {
7805 return _this.handleBlur();
7806 }));
7807
7808 return _this;
7809 }
7810 /**
7811 * Opens and closes the menu.
7812 * @param {Event} event The event triggering this method.
7813 */
7814
7815
7816 _createClass(ProfileSwitcher, [{
7817 key: "toggle",
7818 value: function toggle(event) {
7819 var isOfSelf = this.element.contains(event.target);
7820
7821 if (event.which === 13 || event.which === 32) {
7822 if (isOfSelf) {
7823 this.element.classList.toggle(this.options.classSwitcherOpen);
7824 } else if (!isOfSelf && this.element.classList.contains(this.options.classSwitcherOpen)) {
7825 this.element.classList.remove(this.options.classSwitcherOpen);
7826 }
7827 }
7828 }
7829 }, {
7830 key: "getLinkedData",
7831 value: function getLinkedData(event) {
7832 if (event.target.querySelector(this.options.selectorLinkedAccount) !== null) {
7833 if (event.target.querySelector(this.options.selectorLinkedAccount).textContent.length > 1) {
7834 this.element.isLinked = true;
7835 } else {
7836 this.element.isLinked = false;
7837 }
7838 }
7839 }
7840 }, {
7841 key: "handleBlur",
7842 value: function handleBlur() {
7843 if (!this.element.contains(document.activeElement)) {
7844 this.element.classList.remove(this.options.classSwitcherOpen);
7845 }
7846 }
7847 /**
7848 * Handles click on the document.
7849 * Closes the profile switcherwhen document is clicked outside the left navigation or
7850 * the user clicks the profile switcher while it is open.
7851 * @param {Event} evt The event triggering this method.
7852 */
7853
7854 }, {
7855 key: "handleDocumentClick",
7856 value: function handleDocumentClick(evt) {
7857 var clickTarget = evt.target;
7858 var isOfSelf = this.element.contains(clickTarget);
7859 var isToggle = eventMatches(evt, this.options.selectorToggle);
7860 var isOpen = this.element.classList.contains(this.options.classSwitcherOpen);
7861
7862 if (isOfSelf) {
7863 if (isToggle && isOpen) {
7864 this.element.classList.remove(this.options.classSwitcherOpen);
7865 } else if (isOpen) {
7866 this.determineSwitcherValues();
7867 } else {
7868 this.element.classList.add(this.options.classSwitcherOpen);
7869 }
7870 } else {
7871 this.element.classList.remove(this.options.classSwitcherOpen);
7872 }
7873 }
7874 /**
7875 * Handles logic to determine what text to display in profile switcher.
7876 * If the text is over 25 characters long, truncate and add ellipses.
7877 * Also adds logic to change the switcher width based on the width of the hovered
7878 * profile switcher
7879 * @param {boolean} isHovered boolean value passed by the event listener on bx--toggle.
7880 */
7881
7882 }, {
7883 key: "determineSwitcherValues",
7884 value: function determineSwitcherValues(isHovered) {
7885 var linkedElement = this.element.querySelector(this.options.selectorLinkedAccount);
7886 var nameElement = this.element.querySelector(this.options.selectorAccount);
7887 var regionElement = this.element.querySelector(this.options.selectorRegion);
7888 var orgElement = this.element.querySelector(this.options.selectorOrg);
7889 var spaceElement = this.element.querySelector(this.options.selectorSpace);
7890 var menuElement = this.element.querySelector(this.options.selectorMenu);
7891 var isOpen = this.element.classList.contains(this.options.classSwitcherOpen);
7892
7893 if (linkedElement) {
7894 if (this.element.isLinked) {
7895 if (this.element.linkedAccount) {
7896 if (linkedElement.textContent.length) {
7897 linkedElement.querySelector(this.options.selectorAccountSlLinked).textContent = this.element.linkedAccount.textContent;
7898 } else {
7899 linkedElement.appendChild(this.element.linkedAccount);
7900
7901 if (this.element.linkedIcon) {
7902 linkedElement.appendChild(this.element.linkedIcon);
7903 }
7904 }
7905 }
7906 } else {
7907 linkedElement.textContent = '';
7908 }
7909 }
7910
7911 var nameDropdownValue = '';
7912
7913 if (this.element.querySelector(this.options.selectorAccountDropdown)) {
7914 if (this.element.isLinked) {
7915 nameDropdownValue = this.element.querySelector(this.options.selectorAccountLinked).textContent;
7916 } else {
7917 nameDropdownValue = this.element.querySelector(this.options.selectorAccountDropdown).textContent;
7918 }
7919 }
7920
7921 var regionDropdownValue = '';
7922
7923 if (this.element.querySelector(this.options.selectorRegionDropdown)) {
7924 regionDropdownValue = this.element.querySelector(this.options.selectorRegionDropdown).textContent;
7925 }
7926
7927 var orgDropdownValue = '';
7928
7929 if (this.element.querySelector(this.options.selectorOrgDropdown)) {
7930 orgDropdownValue = this.element.querySelector(this.options.selectorOrgDropdown).textContent;
7931 }
7932
7933 var spaceDropdownValue = '';
7934
7935 if (this.element.querySelector(this.options.selectorSpaceDropdown)) {
7936 spaceDropdownValue = this.element.querySelector(this.options.selectorSpaceDropdown).textContent;
7937 }
7938
7939 var nameShort;
7940 var orgShort;
7941 var spaceShort;
7942
7943 if (isHovered && !isOpen) {
7944 if (nameElement) {
7945 nameElement.textContent = nameDropdownValue;
7946 }
7947
7948 if (orgElement) {
7949 orgElement.textContent = orgDropdownValue;
7950 }
7951
7952 if (spaceElement) {
7953 spaceElement.textContent = spaceDropdownValue;
7954 }
7955
7956 if (regionElement) {
7957 regionElement.textContent = regionDropdownValue;
7958 }
7959
7960 if (menuElement) {
7961 menuElement.style.width = "".concat(this.element.getBoundingClientRect().width, "px");
7962 }
7963 } else {
7964 if (nameElement) {
7965 if (nameDropdownValue.length > 25) {
7966 nameShort = "".concat(nameDropdownValue.substr(0, 25), "...");
7967 nameElement.textContent = nameShort;
7968 } else {
7969 nameElement.textContent = nameDropdownValue;
7970 }
7971 }
7972
7973 if (orgElement) {
7974 if (orgDropdownValue.length > 25) {
7975 orgShort = "".concat(orgDropdownValue.slice(0, 12), "...").concat(orgDropdownValue.slice(-13));
7976 orgElement.textContent = orgShort;
7977 } else {
7978 orgElement.textContent = orgDropdownValue;
7979 }
7980 }
7981
7982 if (spaceElement) {
7983 if (spaceDropdownValue.length > 25) {
7984 spaceShort = "".concat(spaceDropdownValue.substr(0, 25), "...");
7985 spaceElement.textContent = spaceShort;
7986 } else {
7987 spaceElement.textContent = spaceDropdownValue;
7988 }
7989 }
7990
7991 if (regionElement) {
7992 regionElement.textContent = regionDropdownValue;
7993 }
7994
7995 if (menuElement) {
7996 menuElement.style.width = "".concat(this.element.getBoundingClientRect().width, "px");
7997 }
7998 }
7999 }
8000 /**
8001 * The component options.
8002 * @member ProfileSwitcher.options
8003 * @type {Object}
8004 * @property {string} selectorInit The CSS selector to find profile switchers.
8005 * @property {string} [selectorProfileSwitcher] The data attribute selector for the profile switcher.
8006 * @property {string} [selectorAccount]
8007 * The data attribute selector for the element containing the account name in the profile switcher.
8008 * @property {string} [selectorOrg]
8009 * The data attribute selector for the element containing the organization name in the profile switcher.
8010 * @property {string} [selectorSpace]
8011 * The data attribute selector for the element containing the space name in the profile switcher.
8012 * @property {string} [selectorAccountDropdown]
8013 * The data attribute selector for the dropdown item containing the current account name.
8014 * @property {string} [selectorOrgDropdown]
8015 * The data attribute selector for the dropdown item containing the current organization name.
8016 * @property {string} [selectorSpaceDropdown]
8017 * The data attribute selector for the dropdown item containing the current space name.
8018 */
8019
8020 }], [{
8021 key: "options",
8022 get: function get() {
8023 var prefix = settings_1.prefix;
8024 return {
8025 selectorInit: '[data-profile-switcher]',
8026 // Data Attribute selectors
8027 selectorProfileSwitcher: '[data-profile-switcher]',
8028 selectorToggle: '[data-profile-switcher-toggle]',
8029 selectorMenu: '[data-switcher-menu]',
8030 selectorLinkedAccount: '[data-switcher-account-sl]',
8031 selectorAccount: '[data-switcher-account]',
8032 selectorRegion: '[data-switcher-region]',
8033 selectorOrg: '[data-switcher-org]',
8034 selectorSpace: '[data-switcher-space]',
8035 selectorDropdown: '[data-dropdown]',
8036 selectorAccountDropdown: '[data-dropdown-account]',
8037 selectorAccountSlDropdown: '[data-dropdown-account-sl]',
8038 selectorAccountLinked: '[data-dropdown-account-linked]',
8039 selectorAccountSlLinked: '[data-dropdown-account-sl-linked]',
8040 selectorRegionDropdown: '[data-dropdown-region]',
8041 selectorOrgDropdown: '[data-dropdown-org]',
8042 selectorSpaceDropdown: '[data-dropdown-space]',
8043 classSwitcherOpen: "".concat(prefix, "--account-switcher--open"),
8044 classLinkedIcon: ".".concat(prefix, "--account-switcher__linked-icon")
8045 };
8046 }
8047 /**
8048 * The map associating DOM element and profile switcher instance.
8049 * @member ProfileSwitcher.components
8050 * @type {WeakMap}
8051 */
8052
8053 }]);
8054
8055 return ProfileSwitcher;
8056 }(mixin(createComponent, initComponentBySearch, handles));
8057
8058 _defineProperty(ProfileSwitcher, "components",
8059 /* #__PURE_CLASS_PROPERTY__ */
8060 new WeakMap());
8061
8062 var profileSwitcher = !breakingChangesX ? ProfileSwitcher : removedComponent('ProfileSwitcher');
8063
8064 var Pagination =
8065 /*#__PURE__*/
8066 function (_mixin) {
8067 _inherits(Pagination, _mixin);
8068
8069 /**
8070 * Pagination component.
8071 * @extends CreateComponent
8072 * @extends InitComponentBySearch
8073 * @param {HTMLElement} element The element working as a pagination component.
8074 * @param {Object} [options] The component options.
8075 * @property {string} [selectorInit] The CSS selector to find pagination components.
8076 * @property {string} [selectorItemsPerPageInput]
8077 * The CSS selector to find the input that determines the number of items per page.
8078 * @property {string} [selectorPageNumberInput] The CSS selector to find the input that changes the page displayed.
8079 * @property {string} [selectorPageBackward] The CSS selector to find the button that goes back a page.
8080 * @property {string} [selectorPageForward] The CSS selector to find the button that goes forward a page.
8081 * @property {string} [eventItemsPerPage]
8082 * The name of the custom event fired when a user changes the number of items per page.
8083 * event.detail.value contains the number of items a user wishes to see.
8084 * @property {string} [eventPageNumber]
8085 * The name of the custom event fired when a user inputs a specific page number.
8086 * event.detail.value contains the value that the user input.
8087 * @property {string} [eventPageChange]
8088 * The name of the custom event fired when a user goes forward or backward a page.
8089 * event.detail.direction contains the direction a user wishes to go.
8090 */
8091 function Pagination(element, options) {
8092 var _this;
8093
8094 _classCallCheck(this, Pagination);
8095
8096 _this = _possibleConstructorReturn(this, _getPrototypeOf(Pagination).call(this, element, options));
8097
8098 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_emitEvent", function (evtName, detail) {
8099 var event = new CustomEvent("".concat(evtName), {
8100 bubbles: true,
8101 cancelable: true,
8102 detail: detail
8103 });
8104
8105 _this.element.dispatchEvent(event);
8106 });
8107
8108 _this.manage(on(_this.element, 'click', function (evt) {
8109 if (evt.target.matches(_this.options.selectorPageBackward)) {
8110 var detail = {
8111 initialEvt: evt,
8112 element: evt.target,
8113 direction: 'backward'
8114 };
8115
8116 _this._emitEvent(_this.options.eventPageChange, detail);
8117 } else if (evt.target.matches(_this.options.selectorPageForward)) {
8118 var _detail = {
8119 initialEvt: evt,
8120 element: evt.target,
8121 direction: 'forward'
8122 };
8123
8124 _this._emitEvent(_this.options.eventPageChange, _detail);
8125 }
8126 }));
8127
8128 _this.manage(on(_this.element, 'input', function (evt) {
8129 if (evt.target.matches(_this.options.selectorItemsPerPageInput)) {
8130 var detail = {
8131 initialEvt: evt,
8132 element: evt.target,
8133 value: evt.target.value
8134 };
8135
8136 _this._emitEvent(_this.options.eventItemsPerPage, detail);
8137 } else if (evt.target.matches(_this.options.selectorPageNumberInput)) {
8138 var _detail2 = {
8139 initialEvt: evt,
8140 element: evt.target,
8141 value: evt.target.value
8142 };
8143
8144 _this._emitEvent(_this.options.eventPageNumber, _detail2);
8145 }
8146 }));
8147
8148 return _this;
8149 }
8150 /**
8151 * Dispatches a custom event
8152 * @param {string} evtName name of the event to be dispatched.
8153 * @param {Object} detail contains the original event and any other necessary details.
8154 */
8155
8156
8157 return Pagination;
8158 }(mixin(createComponent, initComponentBySearch, handles));
8159
8160 _defineProperty(Pagination, "components",
8161 /* #__PURE_CLASS_PROPERTY__ */
8162 new WeakMap());
8163
8164 _defineProperty(Pagination, "options",
8165 /* #__PURE_CLASS_PROPERTY__ */
8166 {
8167 selectorInit: '[data-pagination]',
8168 selectorItemsPerPageInput: '[data-items-per-page]',
8169 selectorPageNumberInput: '[data-page-number-input]',
8170 selectorPageBackward: '[data-page-backward]',
8171 selectorPageForward: '[data-page-forward]',
8172 eventItemsPerPage: 'itemsPerPage',
8173 eventPageNumber: 'pageNumber',
8174 eventPageChange: 'pageChange'
8175 });
8176
8177 /**
8178 * Copyright IBM Corp. 2016, 2018
8179 *
8180 * This source code is licensed under the Apache-2.0 license found in the
8181 * LICENSE file in the root directory of this source tree.
8182 */
8183 function svgToggleClass(svg, name, forceAdd) {
8184 var list = svg.getAttribute('class').trim().split(/\s+/);
8185 var uniqueList = Object.keys(list.reduce(function (o, item) {
8186 return Object.assign(o, _defineProperty({}, item, 1));
8187 }, {}));
8188 var index = uniqueList.indexOf(name);
8189 var found = index >= 0;
8190 var add = forceAdd === undefined ? !found : forceAdd;
8191
8192 if (found === !add) {
8193 if (add) {
8194 uniqueList.push(name);
8195 } else {
8196 uniqueList.splice(index, 1);
8197 }
8198
8199 svg.setAttribute('class', uniqueList.join(' '));
8200 }
8201 }
8202
8203 var toArray$8 = function toArray(arrayLike) {
8204 return Array.prototype.slice.call(arrayLike);
8205 };
8206
8207 var Search =
8208 /*#__PURE__*/
8209 function (_mixin) {
8210 _inherits(Search, _mixin);
8211
8212 /**
8213 * Search with Options.
8214 * @extends CreateComponent
8215 * @extends InitComponentBySearch
8216 * @extends Handles
8217 * @param {HTMLElement} element The element working as the search component.
8218 * @param {Object} [options] The component options
8219 * @property {string} [options.selectorInit]
8220 * The selector to find search UIs with options.
8221 * @property {string} [options.selectorSearchView]
8222 * The selector to find the search view icon containers.
8223 * @property {string} [options.selectorSearchInput]
8224 * The selector to find the search input.
8225 * @property {string} [options.selectorClearIcon]
8226 * The selector for the clear icon that clears the search box.
8227 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
8228 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
8229 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
8230 */
8231 function Search(element, options) {
8232 var _this;
8233
8234 _classCallCheck(this, Search);
8235
8236 _this = _possibleConstructorReturn(this, _getPrototypeOf(Search).call(this, element, options));
8237
8238 var closeIcon = _this.element.querySelector(_this.options.selectorClearIcon);
8239
8240 var input = _this.element.querySelector(_this.options.selectorSearchInput);
8241
8242 if (!input) {
8243 throw new Error('Cannot find the search input.');
8244 }
8245
8246 if (closeIcon) {
8247 _this.manage(on(closeIcon, 'click', function () {
8248 svgToggleClass(closeIcon, _this.options.classClearHidden, true);
8249 input.value = '';
8250 input.focus();
8251 }));
8252 }
8253
8254 _this.manage(on(_this.element, 'click', function (evt) {
8255 var toggleItem = eventMatches(evt, _this.options.selectorIconContainer);
8256 if (toggleItem) _this.toggleLayout(toggleItem);
8257 }));
8258
8259 _this.manage(on(input, 'input', function (evt) {
8260 if (closeIcon) _this.showClear(evt.target.value, closeIcon);
8261 }));
8262
8263 return _this;
8264 }
8265 /**
8266 * Toggles between the grid and list layout.
8267 * @param {HTMLElement} element The element contining the layout toggle.
8268 */
8269
8270
8271 _createClass(Search, [{
8272 key: "toggleLayout",
8273 value: function toggleLayout(element) {
8274 var _this2 = this;
8275
8276 toArray$8(element.querySelectorAll(this.options.selectorSearchView)).forEach(function (item) {
8277 item.classList.toggle(_this2.options.classLayoutHidden);
8278 });
8279 }
8280 /**
8281 * Toggles the clear icon visibility
8282 * @param {HTMLElement} value The element serving as the search input.
8283 * @param {HTMLElement} icon The element serving as close icon.
8284 */
8285
8286 }, {
8287 key: "showClear",
8288 value: function showClear(value, icon) {
8289 svgToggleClass(icon, this.options.classClearHidden, value.length === 0);
8290 }
8291 /**
8292 * The component options.
8293 * If `options` is specified in the constructor,
8294 * {@linkcode Search.create .create()}, or {@linkcode Search.init .init()},
8295 * properties in this object are overriden for the instance being created
8296 * and how {@linkcode Search.init .init()} works.
8297 * @member Search.options
8298 * @type {Object}
8299 * @property {string} [options.selectorInit]
8300 * The selector to find search UIs with options.
8301 * @property {string} [options.selectorSearchView]
8302 * The selector to find the search view icon containers.
8303 * @property {string} [options.selectorSearchInput]
8304 * The selector to find the search input.
8305 * @property {string} [options.selectorClearIcon]
8306 * The selector for the clear icon that clears the search box.
8307 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
8308 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
8309 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
8310 */
8311
8312 }], [{
8313 key: "options",
8314 get: function get() {
8315 var prefix = settings_1.prefix;
8316 return {
8317 selectorInit: '[data-search]',
8318 selectorSearchView: '[data-search-view]',
8319 selectorSearchInput: ".".concat(prefix, "--search-input"),
8320 selectorClearIcon: ".".concat(prefix, "--search-close"),
8321 selectorIconContainer: ".".concat(prefix, "--search-button[data-search-toggle]"),
8322 classClearHidden: "".concat(prefix, "--search-close--hidden"),
8323 classLayoutHidden: "".concat(prefix, "--search-view--hidden")
8324 };
8325 }
8326 /**
8327 * The map associating DOM element and search instance.
8328 * @member Search.components
8329 * @type {WeakMap}
8330 */
8331
8332 }]);
8333
8334 return Search;
8335 }(mixin(createComponent, initComponentBySearch, handles));
8336
8337 _defineProperty(Search, "components",
8338 /* #__PURE_CLASS_PROPERTY__ */
8339 new WeakMap());
8340
8341 var Accordion =
8342 /*#__PURE__*/
8343 function (_mixin) {
8344 _inherits(Accordion, _mixin);
8345
8346 /**
8347 * Accordion.
8348 * @extends CreateComponent
8349 * @extends InitComponentBySearch
8350 * @extends Handles
8351 * @param {HTMLElement} element The element working as an accordion.
8352 */
8353 function Accordion(element, options) {
8354 var _this;
8355
8356 _classCallCheck(this, Accordion);
8357
8358 _this = _possibleConstructorReturn(this, _getPrototypeOf(Accordion).call(this, element, options));
8359
8360 _this.manage(on(_this.element, 'click', function (event) {
8361 var item = eventMatches(event, _this.options.selectorAccordionItem);
8362
8363 if (item && !eventMatches(event, _this.options.selectorAccordionContent)) {
8364 _this._toggle(item);
8365 }
8366 }));
8367 /**
8368 *
8369 * DEPRECATE in v8
8370 *
8371 * Swapping to a button elemenet instead of a div
8372 * automatically maps click events to keypress as well
8373 * This event listener now is only added if user is using
8374 * the older markup
8375 */
8376
8377
8378 if (!_this._checkIfButton()) {
8379 _this.manage(on(_this.element, 'keypress', function (event) {
8380 var item = eventMatches(event, _this.options.selectorAccordionItem);
8381
8382 if (item && !eventMatches(event, _this.options.selectorAccordionContent)) {
8383 _this._handleKeypress(event);
8384 }
8385 }));
8386 }
8387
8388 return _this;
8389 }
8390
8391 _createClass(Accordion, [{
8392 key: "_checkIfButton",
8393 value: function _checkIfButton() {
8394 return this.element.firstElementChild.firstElementChild.nodeName === 'BUTTON';
8395 }
8396 /**
8397 * Handles toggling of active state of accordion via keyboard
8398 * @param {Event} event The event triggering this method.
8399 */
8400
8401 }, {
8402 key: "_handleKeypress",
8403 value: function _handleKeypress(event) {
8404 if (event.which === 13 || event.which === 32) {
8405 this._toggle(event.target);
8406 }
8407 }
8408 }, {
8409 key: "_toggle",
8410 value: function _toggle(element) {
8411 var heading = element.querySelector(this.options.selectorAccordionItemHeading);
8412 var expanded = heading.getAttribute('aria-expanded');
8413
8414 if (expanded !== null) {
8415 heading.setAttribute('aria-expanded', expanded === 'true' ? 'false' : 'true');
8416 }
8417
8418 element.classList.toggle(this.options.classActive);
8419 }
8420 /**
8421 * The component options.
8422 * If `options` is specified in the constructor,
8423 * {@linkcode NumberInput.create .create()}, or {@linkcode NumberInput.init .init()},
8424 * properties in this object are overriden for the instance being create and how {@linkcode NumberInput.init .init()} works.
8425 * @property {string} selectorInit The CSS selector to find accordion UIs.
8426 */
8427
8428 }], [{
8429 key: "options",
8430 get: function get() {
8431 var prefix = settings_1.prefix;
8432 return {
8433 selectorInit: '[data-accordion]',
8434 selectorAccordionItem: ".".concat(prefix, "--accordion__item"),
8435 selectorAccordionItemHeading: ".".concat(prefix, "--accordion__heading"),
8436 selectorAccordionContent: ".".concat(prefix, "--accordion__content"),
8437 classActive: "".concat(prefix, "--accordion__item--active")
8438 };
8439 }
8440 /**
8441 * The map associating DOM element and accordion UI instance.
8442 * @type {WeakMap}
8443 */
8444
8445 }]);
8446
8447 return Accordion;
8448 }(mixin(createComponent, initComponentBySearch, handles));
8449
8450 _defineProperty(Accordion, "components",
8451 /* #__PURE_CLASS_PROPERTY__ */
8452 new WeakMap());
8453
8454 var CopyButton =
8455 /*#__PURE__*/
8456 function (_mixin) {
8457 _inherits(CopyButton, _mixin);
8458
8459 /**
8460 * CopyBtn UI.
8461 * @extends CreateComponent
8462 * @extends InitComponentBySearch
8463 * @extends Handles
8464 * @param {HTMLElement} element The element working as a copy button UI.
8465 */
8466 function CopyButton(element, options) {
8467 var _this;
8468
8469 _classCallCheck(this, CopyButton);
8470
8471 _this = _possibleConstructorReturn(this, _getPrototypeOf(CopyButton).call(this, element, options));
8472
8473 _this.manage(on(_this.element, 'click', function () {
8474 return _this.handleClick();
8475 }));
8476
8477 return _this;
8478 }
8479 /**
8480 * Show the feedback tooltip on click. Hide the feedback tooltip after specified timeout value.
8481 */
8482
8483
8484 _createClass(CopyButton, [{
8485 key: "handleClick",
8486 value: function handleClick() {
8487 var _this2 = this;
8488
8489 var feedback = this.element.querySelector(this.options.feedbackTooltip);
8490
8491 if (feedback) {
8492 feedback.classList.add(this.options.classShowFeedback);
8493 setTimeout(function () {
8494 feedback.classList.remove(_this2.options.classShowFeedback);
8495 }, this.options.timeoutValue);
8496 }
8497 }
8498 /**
8499 * The map associating DOM element and copy button UI instance.
8500 * @member CopyBtn.components
8501 * @type {WeakMap}
8502 */
8503
8504 }], [{
8505 key: "options",
8506
8507 /**
8508 * The component options.
8509 * If `options` is specified in the constructor, {@linkcode CopyBtn.create .create()}, or {@linkcode CopyBtn.init .init()},
8510 * properties in this object are overriden for the instance being create and how {@linkcode CopyBtn.init .init()} works.
8511 * @member CopyBtn.options
8512 * @type {Object}
8513 * @property {string} selectorInit The data attribute to find copy button UIs.
8514 * @property {string} feedbackTooltip The data attribute to find feedback tooltip.
8515 * @property {string} classShowFeedback The CSS selector for showing the feedback tooltip.
8516 * @property {number} timeoutValue The specified timeout value before the feedback tooltip is hidden.
8517 */
8518 get: function get() {
8519 var prefix = settings_1.prefix;
8520 return {
8521 selectorInit: '[data-copy-btn]',
8522 feedbackTooltip: '[data-feedback]',
8523 classShowFeedback: "".concat(prefix, "--btn--copy__feedback--displayed"),
8524 timeoutValue: 2000
8525 };
8526 }
8527 }]);
8528
8529 return CopyButton;
8530 }(mixin(createComponent, initComponentBySearch, handles));
8531
8532 _defineProperty(CopyButton, "components",
8533 /* #__PURE_CLASS_PROPERTY__ */
8534 new WeakMap());
8535
8536 var Notification =
8537 /*#__PURE__*/
8538 function (_mixin) {
8539 _inherits(Notification, _mixin);
8540
8541 /**
8542 * InlineNotification.
8543 * @extends CreateComponent
8544 * @extends InitComponentBySearch
8545 * @extends Handles
8546 * @param {HTMLElement} element The element working as a InlineNotification.
8547 */
8548 function Notification(element, options) {
8549 var _this;
8550
8551 _classCallCheck(this, Notification);
8552
8553 _this = _possibleConstructorReturn(this, _getPrototypeOf(Notification).call(this, element, options));
8554
8555 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
8556 if (state === 'delete-notification') {
8557 _this.element.parentNode.removeChild(_this.element);
8558
8559 _this.release();
8560 }
8561
8562 callback();
8563 });
8564
8565 _this.button = element.querySelector(_this.options.selectorButton);
8566
8567 if (_this.button) {
8568 _this.manage(on(_this.button, 'click', function (evt) {
8569 if (evt.currentTarget === _this.button) {
8570 _this.remove();
8571 }
8572 }));
8573 }
8574
8575 return _this;
8576 }
8577
8578 _createClass(Notification, [{
8579 key: "remove",
8580 value: function remove() {
8581 this.changeState('delete-notification');
8582 }
8583 /**
8584 * The map associating DOM element and accordion UI instance.
8585 * @type {WeakMap}
8586 */
8587
8588 }]);
8589
8590 return Notification;
8591 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
8592
8593 _defineProperty(Notification, "components",
8594 /* #__PURE_CLASS_PROPERTY__ */
8595 new WeakMap());
8596
8597 _defineProperty(Notification, "options",
8598 /* #__PURE_CLASS_PROPERTY__ */
8599 {
8600 selectorInit: '[data-notification]',
8601 selectorButton: '[data-notification-btn]',
8602 eventBeforeDeleteNotification: 'notification-before-delete',
8603 eventAfterDeleteNotification: 'notification-after-delete'
8604 });
8605
8606 var toArray$9 = function toArray(arrayLike) {
8607 return Array.prototype.slice.call(arrayLike);
8608 };
8609
8610 var Toolbar =
8611 /*#__PURE__*/
8612 function (_mixin) {
8613 _inherits(Toolbar, _mixin);
8614
8615 /**
8616 * Toolbar.
8617 * @extends CreateComponent
8618 * @extends InitComponentBySearch
8619 * @extends Handles
8620 * @param {HTMLElement} element The element working as an toolbar.
8621 */
8622 function Toolbar(element, options) {
8623 var _this;
8624
8625 _classCallCheck(this, Toolbar);
8626
8627 _this = _possibleConstructorReturn(this, _getPrototypeOf(Toolbar).call(this, element, options));
8628
8629 if (!_this.element.dataset.tableTarget) {
8630 console.warn('There is no table bound to this toolbar!'); // eslint-disable-line no-console
8631 } else {
8632 var boundTable = _this.element.ownerDocument.querySelector(_this.element.dataset.tableTarget);
8633
8634 var rowHeightBtns = _this.element.querySelector(_this.options.selectorRowHeight);
8635
8636 if (rowHeightBtns) {
8637 _this.manage(on(rowHeightBtns, 'click', function (event) {
8638 _this._handleRowHeightChange(event, boundTable);
8639 })); // toArray(this.element.querySelectorAll(this.options.selectorRowHeight)).forEach((item) => {
8640 // item.addEventListener('click', (event) => { this._handleRowHeightChange(event, boundTable); });
8641 // });
8642
8643 }
8644 }
8645
8646 _this.manage(on(_this.element.ownerDocument, 'keydown', function (evt) {
8647 _this._handleKeyDown(evt);
8648 }));
8649
8650 _this.manage(on(_this.element.ownerDocument, 'click', function (evt) {
8651 _this._handleDocumentClick(evt);
8652 }));
8653
8654 return _this;
8655 }
8656 /**
8657 * Handles toggling of active state of the toolbar search input
8658 * @param {Event} event The event triggering this method.
8659 */
8660
8661
8662 _createClass(Toolbar, [{
8663 key: "_handleDocumentClick",
8664 value: function _handleDocumentClick(event) {
8665 var _this2 = this;
8666
8667 var searchInput = eventMatches(event, this.options.selectorSearch);
8668 var isOfSelfSearchInput = searchInput && this.element.contains(searchInput);
8669
8670 if (isOfSelfSearchInput) {
8671 var shouldBeOpen = isOfSelfSearchInput && !this.element.classList.contains(this.options.classSearchActive);
8672 searchInput.classList.toggle(this.options.classSearchActive, shouldBeOpen);
8673
8674 if (shouldBeOpen) {
8675 searchInput.querySelector('input').focus();
8676 }
8677 }
8678
8679 var targetComponentElement = eventMatches(event, this.options.selectorInit);
8680 toArray$9(this.element.ownerDocument.querySelectorAll(this.options.selectorSearch)).forEach(function (item) {
8681 if (!targetComponentElement || !targetComponentElement.contains(item)) {
8682 item.classList.remove(_this2.options.classSearchActive);
8683 }
8684 });
8685 }
8686 /**
8687 * Handles toggling of active state of the toolbar search input via the keyboard
8688 * @param {Event} event The event triggering this method.
8689 */
8690
8691 }, {
8692 key: "_handleKeyDown",
8693 value: function _handleKeyDown(event) {
8694 var searchInput = eventMatches(event, this.options.selectorSearch);
8695
8696 if (searchInput && event.which === 27) {
8697 searchInput.classList.remove(this.options.classSearchActive);
8698 }
8699 }
8700 /**
8701 * Handles toggling of the row height of the associated table
8702 * @param {Event} event The event triggering this method.
8703 * @param {HTMLElement} boundTable The table associated with the toolbar.
8704 */
8705
8706 }, {
8707 key: "_handleRowHeightChange",
8708 value: function _handleRowHeightChange(event, boundTable) {
8709 var _event$currentTarget$ = event.currentTarget.querySelector('input:checked'),
8710 value = _event$currentTarget$.value;
8711
8712 if (value === 'tall') {
8713 boundTable.classList.add(this.options.classTallRows);
8714 } else {
8715 boundTable.classList.remove(this.options.classTallRows);
8716 }
8717 }
8718 /**
8719 * The map associating DOM element and Toolbar UI instance.
8720 * @type {WeakMap}
8721 */
8722
8723 }], [{
8724 key: "options",
8725
8726 /**
8727 * The component options.
8728 * If `options` is specified in the constructor,
8729 * properties in this object are overriden for the instance being created.
8730 * @property {string} selectorInit The CSS selector to find toolbar instances.
8731 * @property {string} selectorSearch The CSS selector to find search inputs in a toolbar.
8732 * @property {string} selectorRowHeight The CSS selector to find the row height inputs in a toolbar.
8733 * @property {string} classTallRows The CSS class for making table rows into tall rows.
8734 * @property {string} classSearchActive The CSS class the active state of the search input.
8735 */
8736 get: function get() {
8737 var prefix = settings_1.prefix;
8738 return {
8739 selectorInit: '[data-toolbar]',
8740 selectorSearch: '[data-toolbar-search]',
8741 selectorRowHeight: '[data-row-height]',
8742 classTallRows: "".concat(prefix, "--responsive-table--tall"),
8743 classSearchActive: "".concat(prefix, "--toolbar-search--active")
8744 };
8745 }
8746 }]);
8747
8748 return Toolbar;
8749 }(mixin(createComponent, initComponentBySearch, handles));
8750
8751 _defineProperty(Toolbar, "components",
8752 /* #__PURE_CLASS_PROPERTY__ */
8753 new WeakMap());
8754
8755 /**
8756 * lodash (Custom Build) <https://lodash.com/>
8757 * Build: `lodash modularize exports="npm" -o ./`
8758 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
8759 * Released under MIT license <https://lodash.com/license>
8760 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
8761 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8762 */
8763
8764 /** Used as the `TypeError` message for "Functions" methods. */
8765 var FUNC_ERROR_TEXT = 'Expected a function';
8766
8767 /** Used as references for various `Number` constants. */
8768 var NAN = 0 / 0;
8769
8770 /** `Object#toString` result references. */
8771 var symbolTag = '[object Symbol]';
8772
8773 /** Used to match leading and trailing whitespace. */
8774 var reTrim = /^\s+|\s+$/g;
8775
8776 /** Used to detect bad signed hexadecimal string values. */
8777 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
8778
8779 /** Used to detect binary string values. */
8780 var reIsBinary = /^0b[01]+$/i;
8781
8782 /** Used to detect octal string values. */
8783 var reIsOctal = /^0o[0-7]+$/i;
8784
8785 /** Built-in method references without a dependency on `root`. */
8786 var freeParseInt = parseInt;
8787
8788 /** Detect free variable `global` from Node.js. */
8789 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
8790
8791 /** Detect free variable `self`. */
8792 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
8793
8794 /** Used as a reference to the global object. */
8795 var root = freeGlobal || freeSelf || Function('return this')();
8796
8797 /** Used for built-in method references. */
8798 var objectProto = Object.prototype;
8799
8800 /**
8801 * Used to resolve the
8802 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
8803 * of values.
8804 */
8805 var objectToString = objectProto.toString;
8806
8807 /* Built-in method references for those with the same name as other `lodash` methods. */
8808 var nativeMax = Math.max,
8809 nativeMin = Math.min;
8810
8811 /**
8812 * Gets the timestamp of the number of milliseconds that have elapsed since
8813 * the Unix epoch (1 January 1970 00:00:00 UTC).
8814 *
8815 * @static
8816 * @memberOf _
8817 * @since 2.4.0
8818 * @category Date
8819 * @returns {number} Returns the timestamp.
8820 * @example
8821 *
8822 * _.defer(function(stamp) {
8823 * console.log(_.now() - stamp);
8824 * }, _.now());
8825 * // => Logs the number of milliseconds it took for the deferred invocation.
8826 */
8827 var now = function() {
8828 return root.Date.now();
8829 };
8830
8831 /**
8832 * Creates a debounced function that delays invoking `func` until after `wait`
8833 * milliseconds have elapsed since the last time the debounced function was
8834 * invoked. The debounced function comes with a `cancel` method to cancel
8835 * delayed `func` invocations and a `flush` method to immediately invoke them.
8836 * Provide `options` to indicate whether `func` should be invoked on the
8837 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8838 * with the last arguments provided to the debounced function. Subsequent
8839 * calls to the debounced function return the result of the last `func`
8840 * invocation.
8841 *
8842 * **Note:** If `leading` and `trailing` options are `true`, `func` is
8843 * invoked on the trailing edge of the timeout only if the debounced function
8844 * is invoked more than once during the `wait` timeout.
8845 *
8846 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
8847 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
8848 *
8849 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
8850 * for details over the differences between `_.debounce` and `_.throttle`.
8851 *
8852 * @static
8853 * @memberOf _
8854 * @since 0.1.0
8855 * @category Function
8856 * @param {Function} func The function to debounce.
8857 * @param {number} [wait=0] The number of milliseconds to delay.
8858 * @param {Object} [options={}] The options object.
8859 * @param {boolean} [options.leading=false]
8860 * Specify invoking on the leading edge of the timeout.
8861 * @param {number} [options.maxWait]
8862 * The maximum time `func` is allowed to be delayed before it's invoked.
8863 * @param {boolean} [options.trailing=true]
8864 * Specify invoking on the trailing edge of the timeout.
8865 * @returns {Function} Returns the new debounced function.
8866 * @example
8867 *
8868 * // Avoid costly calculations while the window size is in flux.
8869 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8870 *
8871 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
8872 * jQuery(element).on('click', _.debounce(sendMail, 300, {
8873 * 'leading': true,
8874 * 'trailing': false
8875 * }));
8876 *
8877 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
8878 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8879 * var source = new EventSource('/stream');
8880 * jQuery(source).on('message', debounced);
8881 *
8882 * // Cancel the trailing debounced invocation.
8883 * jQuery(window).on('popstate', debounced.cancel);
8884 */
8885 function debounce(func, wait, options) {
8886 var lastArgs,
8887 lastThis,
8888 maxWait,
8889 result,
8890 timerId,
8891 lastCallTime,
8892 lastInvokeTime = 0,
8893 leading = false,
8894 maxing = false,
8895 trailing = true;
8896
8897 if (typeof func != 'function') {
8898 throw new TypeError(FUNC_ERROR_TEXT);
8899 }
8900 wait = toNumber(wait) || 0;
8901 if (isObject(options)) {
8902 leading = !!options.leading;
8903 maxing = 'maxWait' in options;
8904 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
8905 trailing = 'trailing' in options ? !!options.trailing : trailing;
8906 }
8907
8908 function invokeFunc(time) {
8909 var args = lastArgs,
8910 thisArg = lastThis;
8911
8912 lastArgs = lastThis = undefined;
8913 lastInvokeTime = time;
8914 result = func.apply(thisArg, args);
8915 return result;
8916 }
8917
8918 function leadingEdge(time) {
8919 // Reset any `maxWait` timer.
8920 lastInvokeTime = time;
8921 // Start the timer for the trailing edge.
8922 timerId = setTimeout(timerExpired, wait);
8923 // Invoke the leading edge.
8924 return leading ? invokeFunc(time) : result;
8925 }
8926
8927 function remainingWait(time) {
8928 var timeSinceLastCall = time - lastCallTime,
8929 timeSinceLastInvoke = time - lastInvokeTime,
8930 result = wait - timeSinceLastCall;
8931
8932 return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
8933 }
8934
8935 function shouldInvoke(time) {
8936 var timeSinceLastCall = time - lastCallTime,
8937 timeSinceLastInvoke = time - lastInvokeTime;
8938
8939 // Either this is the first call, activity has stopped and we're at the
8940 // trailing edge, the system time has gone backwards and we're treating
8941 // it as the trailing edge, or we've hit the `maxWait` limit.
8942 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
8943 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
8944 }
8945
8946 function timerExpired() {
8947 var time = now();
8948 if (shouldInvoke(time)) {
8949 return trailingEdge(time);
8950 }
8951 // Restart the timer.
8952 timerId = setTimeout(timerExpired, remainingWait(time));
8953 }
8954
8955 function trailingEdge(time) {
8956 timerId = undefined;
8957
8958 // Only invoke if we have `lastArgs` which means `func` has been
8959 // debounced at least once.
8960 if (trailing && lastArgs) {
8961 return invokeFunc(time);
8962 }
8963 lastArgs = lastThis = undefined;
8964 return result;
8965 }
8966
8967 function cancel() {
8968 if (timerId !== undefined) {
8969 clearTimeout(timerId);
8970 }
8971 lastInvokeTime = 0;
8972 lastArgs = lastCallTime = lastThis = timerId = undefined;
8973 }
8974
8975 function flush() {
8976 return timerId === undefined ? result : trailingEdge(now());
8977 }
8978
8979 function debounced() {
8980 var time = now(),
8981 isInvoking = shouldInvoke(time);
8982
8983 lastArgs = arguments;
8984 lastThis = this;
8985 lastCallTime = time;
8986
8987 if (isInvoking) {
8988 if (timerId === undefined) {
8989 return leadingEdge(lastCallTime);
8990 }
8991 if (maxing) {
8992 // Handle invocations in a tight loop.
8993 timerId = setTimeout(timerExpired, wait);
8994 return invokeFunc(lastCallTime);
8995 }
8996 }
8997 if (timerId === undefined) {
8998 timerId = setTimeout(timerExpired, wait);
8999 }
9000 return result;
9001 }
9002 debounced.cancel = cancel;
9003 debounced.flush = flush;
9004 return debounced;
9005 }
9006
9007 /**
9008 * Checks if `value` is the
9009 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
9010 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9011 *
9012 * @static
9013 * @memberOf _
9014 * @since 0.1.0
9015 * @category Lang
9016 * @param {*} value The value to check.
9017 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9018 * @example
9019 *
9020 * _.isObject({});
9021 * // => true
9022 *
9023 * _.isObject([1, 2, 3]);
9024 * // => true
9025 *
9026 * _.isObject(_.noop);
9027 * // => true
9028 *
9029 * _.isObject(null);
9030 * // => false
9031 */
9032 function isObject(value) {
9033 var type = typeof value;
9034 return !!value && (type == 'object' || type == 'function');
9035 }
9036
9037 /**
9038 * Checks if `value` is object-like. A value is object-like if it's not `null`
9039 * and has a `typeof` result of "object".
9040 *
9041 * @static
9042 * @memberOf _
9043 * @since 4.0.0
9044 * @category Lang
9045 * @param {*} value The value to check.
9046 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9047 * @example
9048 *
9049 * _.isObjectLike({});
9050 * // => true
9051 *
9052 * _.isObjectLike([1, 2, 3]);
9053 * // => true
9054 *
9055 * _.isObjectLike(_.noop);
9056 * // => false
9057 *
9058 * _.isObjectLike(null);
9059 * // => false
9060 */
9061 function isObjectLike(value) {
9062 return !!value && typeof value == 'object';
9063 }
9064
9065 /**
9066 * Checks if `value` is classified as a `Symbol` primitive or object.
9067 *
9068 * @static
9069 * @memberOf _
9070 * @since 4.0.0
9071 * @category Lang
9072 * @param {*} value The value to check.
9073 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
9074 * @example
9075 *
9076 * _.isSymbol(Symbol.iterator);
9077 * // => true
9078 *
9079 * _.isSymbol('abc');
9080 * // => false
9081 */
9082 function isSymbol(value) {
9083 return typeof value == 'symbol' ||
9084 (isObjectLike(value) && objectToString.call(value) == symbolTag);
9085 }
9086
9087 /**
9088 * Converts `value` to a number.
9089 *
9090 * @static
9091 * @memberOf _
9092 * @since 4.0.0
9093 * @category Lang
9094 * @param {*} value The value to process.
9095 * @returns {number} Returns the number.
9096 * @example
9097 *
9098 * _.toNumber(3.2);
9099 * // => 3.2
9100 *
9101 * _.toNumber(Number.MIN_VALUE);
9102 * // => 5e-324
9103 *
9104 * _.toNumber(Infinity);
9105 * // => Infinity
9106 *
9107 * _.toNumber('3.2');
9108 * // => 3.2
9109 */
9110 function toNumber(value) {
9111 if (typeof value == 'number') {
9112 return value;
9113 }
9114 if (isSymbol(value)) {
9115 return NAN;
9116 }
9117 if (isObject(value)) {
9118 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
9119 value = isObject(other) ? (other + '') : other;
9120 }
9121 if (typeof value != 'string') {
9122 return value === 0 ? value : +value;
9123 }
9124 value = value.replace(reTrim, '');
9125 var isBinary = reIsBinary.test(value);
9126 return (isBinary || reIsOctal.test(value))
9127 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
9128 : (reIsBadHex.test(value) ? NAN : +value);
9129 }
9130
9131 var lodash_debounce = debounce;
9132
9133 /**
9134 * @param {Element} menuBody The menu body with the menu arrow.
9135 * @param {string} menuDirection Where the floating menu menu should be placed relative to the trigger button.
9136 * @returns {FloatingMenu~offset} The adjustment of the floating menu position, upon the position of the menu arrow.
9137 * @private
9138 */
9139
9140 var getMenuOffset$1 = function getMenuOffset(menuBody, menuDirection) {
9141 var _DIRECTION_LEFT$DIREC, _DIRECTION_LEFT$DIREC2;
9142
9143 var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
9144 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];
9145 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];
9146 var values = [arrowPositionProp, 'border-bottom-width'].reduce(function (o, name) {
9147 return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
9148 }, {});
9149 var margin = 0;
9150
9151 if (menuDirection !== DIRECTION_BOTTOM) {
9152 var style = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody);
9153 margin = Number((/^([\d-.]+)px$/.exec(style.getPropertyValue('margin-top')) || [])[1]);
9154 }
9155
9156 values[arrowPositionProp] = values[arrowPositionProp] || -6; // IE, etc.
9157
9158 if (Object.keys(values).every(function (name) {
9159 return !isNaN(values[name]);
9160 })) {
9161 var arrowPosition = values[arrowPositionProp],
9162 borderBottomWidth = values['border-bottom-width'];
9163 return _defineProperty({
9164 left: 0,
9165 top: 0
9166 }, menuPositionAdjustmentProp, Math.sqrt(Math.pow(borderBottomWidth, 2) * 2) - arrowPosition + margin * (menuDirection === DIRECTION_TOP ? 2 : 1));
9167 }
9168
9169 return undefined;
9170 };
9171
9172 var Tooltip =
9173 /*#__PURE__*/
9174 function (_mixin) {
9175 _inherits(Tooltip, _mixin);
9176
9177 /**
9178 * Tooltip.
9179 * @extends CreateComponent
9180 * @extends InitComponentBySearch
9181 * @extends Handles
9182 */
9183 function Tooltip(element, options) {
9184 var _this;
9185
9186 _classCallCheck(this, Tooltip);
9187
9188 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tooltip).call(this, element, options));
9189
9190 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_hasContextMenu", false);
9191
9192 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_debouncedHandleClick", lodash_debounce(_this._handleClick, 200));
9193
9194 _this._hookOn(element);
9195
9196 return _this;
9197 }
9198 /**
9199 * A flag to detect if `oncontextmenu` event is fired right before `focus`/`blur` events.
9200 * @type {boolean}
9201 */
9202
9203
9204 _createClass(Tooltip, [{
9205 key: "createdByEvent",
9206
9207 /**
9208 * A method called when this widget is created upon events.
9209 * @param {Event} event The event triggering the creation.
9210 */
9211 value: function createdByEvent(event) {
9212 var relatedTarget = event.relatedTarget,
9213 type = event.type;
9214
9215 this._debouncedHandleClick({
9216 relatedTarget: relatedTarget,
9217 type: type === 'focusin' ? 'focus' : type,
9218 details: getLaunchingDetails(event)
9219 });
9220 }
9221 /**
9222 * Changes the shown/hidden state.
9223 * @param {string} state The new state.
9224 * @param {Object} detail The detail of the event trigging this action.
9225 * @param {Function} callback Callback called when change in state completes.
9226 // */
9227
9228 }, {
9229 key: "changeState",
9230 value: function changeState(state, detail, callback) {
9231 if (!this.tooltip) {
9232 var tooltip = this.element.ownerDocument.querySelector(this.element.getAttribute(this.options.attribTooltipTarget));
9233
9234 if (!tooltip) {
9235 throw new Error('Cannot find the target tooltip.');
9236 } // Lazily create a component instance for tooltip
9237
9238
9239 this.tooltip = FloatingMenu.create(tooltip, {
9240 refNode: this.element,
9241 classShown: this.options.classShown,
9242 offset: this.options.objMenuOffset
9243 });
9244
9245 this._hookOn(tooltip);
9246
9247 this.children.push(this.tooltip);
9248 } // Delegates the action of changing state to the tooltip.
9249 // (And thus the before/after shown/hidden events are fired from the tooltip)
9250
9251
9252 this.tooltip.changeState(state, Object.assign(detail, {
9253 delegatorNode: this.element
9254 }), callback);
9255 }
9256 /**
9257 * Attaches event handlers to show/hide the tooltip.
9258 * @param {Element} element The element to attach the events to.
9259 * @private
9260 */
9261
9262 }, {
9263 key: "_hookOn",
9264 value: function _hookOn(element) {
9265 var _this2 = this;
9266
9267 var hasFocusin = 'onfocusin' in window;
9268 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
9269 [focusinEventName, 'blur', 'touchleave', 'touchcancel'].forEach(function (name) {
9270 _this2.manage(on(element, name, function (event) {
9271 var relatedTarget = event.relatedTarget,
9272 type = event.type;
9273 var hadContextMenu = _this2._hasContextMenu;
9274 _this2._hasContextMenu = type === 'contextmenu';
9275
9276 _this2._debouncedHandleClick({
9277 relatedTarget: relatedTarget,
9278 type: type === 'focusin' ? 'focus' : type,
9279 hadContextMenu: hadContextMenu,
9280 details: getLaunchingDetails(event)
9281 });
9282 }, name === focusinEventName && !hasFocusin));
9283 });
9284 }
9285 /**
9286 * Handles click/focus events.
9287 * @param {Object} params The parameters.
9288 * @param {Element} params.relatedTarget The element that focus went to. (For `blur` event)
9289 * @param {string} params.type The event type triggering this method.
9290 * @param {boolean} params.hadContextMenu
9291 * @param {Object} params.details The event details.
9292 * @private
9293 */
9294
9295 }, {
9296 key: "_handleClick",
9297 value: function _handleClick(_ref2) {
9298 var relatedTarget = _ref2.relatedTarget,
9299 type = _ref2.type,
9300 hadContextMenu = _ref2.hadContextMenu,
9301 details = _ref2.details;
9302 var state = {
9303 focus: 'shown',
9304 blur: 'hidden',
9305 touchleave: 'hidden',
9306 touchcancel: 'hidden'
9307 }[type];
9308 var shouldPreventClose;
9309
9310 if (type === 'blur') {
9311 // Note: SVGElement in IE11 does not have `.contains()`
9312 var wentToSelf = relatedTarget && this.element.contains && this.element.contains(relatedTarget) || this.tooltip && this.tooltip.element.contains(relatedTarget);
9313 shouldPreventClose = hadContextMenu || wentToSelf;
9314 }
9315
9316 if (!shouldPreventClose) {
9317 this.changeState(state, details);
9318 }
9319 }
9320 }], [{
9321 key: "options",
9322 get: function get() {
9323 var prefix = settings_1.prefix;
9324 return {
9325 selectorInit: '[data-tooltip-trigger]',
9326 classShown: "".concat(prefix, "--tooltip--shown"),
9327 attribTooltipTarget: 'data-tooltip-target',
9328 objMenuOffset: getMenuOffset$1,
9329 initEventNames: ['focus']
9330 };
9331 }
9332 }]);
9333
9334 return Tooltip;
9335 }(mixin(createComponent, initComponentByEvent, exports$1, handles));
9336
9337 _defineProperty(Tooltip, "components",
9338 /* #__PURE_CLASS_PROPERTY__ */
9339 new WeakMap());
9340
9341 var toArray$a = function toArray(arrayLike) {
9342 return Array.prototype.slice.call(arrayLike);
9343 };
9344
9345 var ProgressIndicator =
9346 /*#__PURE__*/
9347 function (_mixin) {
9348 _inherits(ProgressIndicator, _mixin);
9349
9350 /**
9351 * ProgressIndicator.
9352 * @extends CreateComponent
9353 * @extends InitComponentBySearch
9354 * @param {HTMLElement} element The element representing the ProgressIndicator.
9355 * @param {Object} [options] The component options.
9356 * @property {string} [options.selectorStepElement] The CSS selector to find step elements.
9357 * @property {string} [options.selectorCurrent] The CSS selector to find the current step element.
9358 * @property {string} [options.selectorIncomplete] The CSS class to find incomplete step elements.
9359 * @property {string} [options.selectorComplete] The CSS selector to find completed step elements.
9360 * @property {string} [options.classStep] The className for a step element.
9361 * @property {string} [options.classComplete] The className for a completed step element.
9362 * @property {string} [options.classCurrent] The className for the current step element.
9363 * @property {string} [options.classIncomplete] The className for a incomplete step element.
9364 */
9365 function ProgressIndicator(element, options) {
9366 var _this;
9367
9368 _classCallCheck(this, ProgressIndicator);
9369
9370 _this = _possibleConstructorReturn(this, _getPrototypeOf(ProgressIndicator).call(this, element, options));
9371 /**
9372 * The component state.
9373 * @type {Object}
9374 */
9375
9376 _this.state = {
9377 /**
9378 * The current step index.
9379 * @type {number}
9380 */
9381 currentIndex: _this.getCurrent().index,
9382
9383 /**
9384 * Total number of steps.
9385 * @type {number}
9386 */
9387 totalSteps: _this.getSteps().length
9388 };
9389
9390 _this.addOverflowTooltip();
9391
9392 return _this;
9393 }
9394 /**
9395 * Returns all steps with details about element and index.
9396 */
9397
9398
9399 _createClass(ProgressIndicator, [{
9400 key: "getSteps",
9401 value: function getSteps() {
9402 return toArray$a(this.element.querySelectorAll(this.options.selectorStepElement)).map(function (element, index) {
9403 return {
9404 element: element,
9405 index: index
9406 };
9407 });
9408 }
9409 /**
9410 * Returns current step; gives detail about element and index.
9411 */
9412
9413 }, {
9414 key: "getCurrent",
9415 value: function getCurrent() {
9416 var currentEl = this.element.querySelector(this.options.selectorCurrent);
9417 return this.getSteps().filter(function (step) {
9418 return step.element === currentEl;
9419 })[0];
9420 }
9421 /**
9422 * Sets the current step.
9423 * * @param {Number} new step index or use default in `this.state.currentIndex`.
9424 */
9425
9426 }, {
9427 key: "setCurrent",
9428 value: function setCurrent() {
9429 var _this2 = this;
9430
9431 var newCurrentStep = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.currentIndex;
9432 var changed = false;
9433
9434 if (newCurrentStep !== this.state.currentIndex) {
9435 this.state.currentIndex = newCurrentStep;
9436 changed = true;
9437 }
9438
9439 if (changed) {
9440 this.getSteps().forEach(function (step) {
9441 if (step.index < newCurrentStep) {
9442 _this2._updateStep({
9443 element: step.element,
9444 className: _this2.options.classComplete,
9445 html: _this2._getSVGComplete()
9446 });
9447 }
9448
9449 if (step.index === newCurrentStep) {
9450 _this2._updateStep({
9451 element: step.element,
9452 className: _this2.options.classCurrent,
9453 html: _this2._getCurrentSVG()
9454 });
9455 }
9456
9457 if (step.index > newCurrentStep) {
9458 _this2._updateStep({
9459 element: step.element,
9460 className: _this2.options.classIncomplete,
9461 html: _this2._getIncompleteSVG()
9462 });
9463 }
9464 });
9465 }
9466 }
9467 /**
9468 * Update step with correct inline SVG and className
9469 * @param {Object} args
9470 * @param {Object} [args.element] target element
9471 * @param {Object} [args.className] new className
9472 * @param {Object} [args.html] new inline SVG to insert
9473 */
9474
9475 }, {
9476 key: "_updateStep",
9477 value: function _updateStep(args) {
9478 var element = args.element,
9479 className = args.className,
9480 html = args.html;
9481
9482 if (element.firstElementChild) {
9483 element.removeChild(element.firstElementChild);
9484 }
9485
9486 if (!element.classList.contains(className)) {
9487 element.setAttribute('class', this.options.classStep);
9488 element.classList.add(className);
9489 }
9490
9491 element.insertAdjacentHTML('afterbegin', html);
9492 }
9493 /**
9494 * Returns HTML string for an SVG used to represent a compelted step (checkmark)
9495 */
9496
9497 }, {
9498 key: "_getSVGComplete",
9499 value: function _getSVGComplete() {
9500 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>";
9501 }
9502 /**
9503 * Returns HTML string for an SVG used to represent current step (circles, like a radio button, but not.)
9504 */
9505
9506 }, {
9507 key: "_getCurrentSVG",
9508 value: function _getCurrentSVG() {
9509 return "<svg>\n <circle cx=\"12\" cy=\"12\" r=\"12\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"6\"></circle>\n </svg>";
9510 }
9511 /**
9512 * Returns HTML string for an SVG used to represent incomple step (grey empty circle)
9513 */
9514
9515 }, {
9516 key: "_getIncompleteSVG",
9517 value: function _getIncompleteSVG() {
9518 return "<svg>\n <circle cx=\"12\" cy=\"12\" r=\"12\"></circle>\n </svg>";
9519 }
9520 }, {
9521 key: "addOverflowTooltip",
9522 value: function addOverflowTooltip() {
9523 var _this3 = this;
9524
9525 var stepLabels = toArray$a(this.element.querySelectorAll(this.options.selectorLabel));
9526 var tooltips = toArray$a(this.element.querySelectorAll(this.options.selectorTooltip));
9527 stepLabels.forEach(function (step) {
9528 if (step.scrollWidth > _this3.options.maxWidth) {
9529 step.classList.add(_this3.options.classOverflowLabel);
9530 }
9531 });
9532 tooltips.forEach(function (tooltip) {
9533 var childText = tooltip.querySelector(_this3.options.selectorTooltipText);
9534
9535 if (childText.scrollHeight > _this3.options.tooltipMaxHeight) {
9536 tooltip.classList.add(_this3.options.classTooltipMulti);
9537 }
9538 });
9539 }
9540 }], [{
9541 key: "options",
9542
9543 /**
9544 * The component options.
9545 * If `options` is specified in the constructor,
9546 * {@linkcode ProgressIndicator.create .create()}, or {@linkcode ProgressIndicator.init .init()},
9547 * properties in this object are overriden for the instance being created.
9548 * @member ProgressIndicator.options
9549 * @type {Object}
9550 * @property {string} selectorInit The CSS selector to find content switcher button set.
9551 * @property {string} [selectorStepElement] The CSS selector to find step elements.
9552 * @property {string} [selectorCurrent] The CSS selector to find the current step element.
9553 * @property {string} [selectorIncomplete] The CSS class to find incomplete step elements.
9554 * @property {string} [selectorComplete] The CSS selector to find completed step elements.
9555 * @property {string} [classStep] The className for a step element.
9556 * @property {string} [classComplete] The className for a completed step element.
9557 * @property {string} [classCurrent] The className for the current step element.
9558 * @property {string} [classIncomplete] The className for a incomplete step element.
9559 */
9560 get: function get() {
9561 var prefix = settings_1.prefix;
9562 return {
9563 selectorInit: '[data-progress]',
9564 selectorStepElement: ".".concat(prefix, "--progress-step"),
9565 selectorCurrent: ".".concat(prefix, "--progress-step--current"),
9566 selectorIncomplete: ".".concat(prefix, "--progress-step--incomplete"),
9567 selectorComplete: ".".concat(prefix, "--progress-step--complete"),
9568 selectorLabel: ".".concat(prefix, "--progress-label"),
9569 selectorTooltip: ".".concat(prefix, "--tooltip"),
9570 selectorTooltipText: ".".concat(prefix, "--tooltip__text"),
9571 classStep: "".concat(prefix, "--progress-step"),
9572 classComplete: "".concat(prefix, "--progress-step--complete"),
9573 classCurrent: "".concat(prefix, "--progress-step--current"),
9574 classIncomplete: "".concat(prefix, "--progress-step--incomplete"),
9575 classOverflowLabel: "".concat(prefix, "--progress-label-overflow"),
9576 classTooltipMulti: "".concat(prefix, "--tooltip_multi"),
9577 maxWidth: 87,
9578 tooltipMaxHeight: 21
9579 };
9580 }
9581 }]);
9582
9583 return ProgressIndicator;
9584 }(mixin(createComponent, initComponentBySearch));
9585
9586 _defineProperty(ProgressIndicator, "components",
9587 /* #__PURE_CLASS_PROPERTY__ */
9588 new WeakMap());
9589
9590 var toArray$b = function toArray(arrayLike) {
9591 return Array.prototype.slice.call(arrayLike);
9592 };
9593
9594 var StructuredList =
9595 /*#__PURE__*/
9596 function (_mixin) {
9597 _inherits(StructuredList, _mixin);
9598
9599 /**
9600 * StructuredList
9601 * @extends CreateComponent
9602 * @extends InitComponentBySearch
9603 * @extends Handles
9604 * @param {HTMLElement} element The root element of tables
9605 * @param {Object} [options] the... options
9606 * @param {string} [options.selectorInit] selector initialization
9607 * @param {string} [options.selectorRow] css selector for selected row
9608 */
9609 function StructuredList(element, options) {
9610 var _this;
9611
9612 _classCallCheck(this, StructuredList);
9613
9614 _this = _possibleConstructorReturn(this, _getPrototypeOf(StructuredList).call(this, element, options));
9615
9616 _this.manage(on(_this.element, 'keydown', function (evt) {
9617 if (evt.which === 37 || evt.which === 38 || evt.which === 39 || evt.which === 40) {
9618 _this._handleKeydownArrow(evt);
9619 }
9620
9621 if (evt.which === 13 || evt.which === 32) {
9622 _this._handleKeydownChecked(evt);
9623 }
9624 }));
9625
9626 _this.manage(on(_this.element, 'click', function (evt) {
9627 _this._handleClick(evt);
9628 }));
9629
9630 return _this;
9631 }
9632
9633 _createClass(StructuredList, [{
9634 key: "_direction",
9635 value: function _direction(evt) {
9636 return {
9637 37: -1,
9638 // backward
9639 38: -1,
9640 // backward
9641 39: 1,
9642 // forward
9643 40: 1 // forward
9644
9645 }[evt.which];
9646 }
9647 }, {
9648 key: "_nextIndex",
9649 value: function _nextIndex(array, arrayItem, direction) {
9650 return array.indexOf(arrayItem) + direction; // returns -1, 0, 1, 2, 3, 4...
9651 }
9652 }, {
9653 key: "_getInput",
9654 value: function _getInput(index) {
9655 var rows = toArray$b(this.element.querySelectorAll(this.options.selectorRow));
9656 return this.element.ownerDocument.querySelector(this.options.selectorListInput(rows[index].getAttribute('for')));
9657 }
9658 }, {
9659 key: "_handleInputChecked",
9660 value: function _handleInputChecked(index) {
9661 var rows = this.element.querySelectorAll(this.options.selectorRow);
9662 var input = this.getInput(index) || rows[index].querySelector('input');
9663 input.checked = true;
9664 }
9665 }, {
9666 key: "_handleClick",
9667 value: function _handleClick(evt) {
9668 var _this2 = this;
9669
9670 var selectedRow = eventMatches(evt, this.options.selectorRow);
9671 toArray$b(this.element.querySelectorAll(this.options.selectorRow)).forEach(function (row) {
9672 return row.classList.remove(_this2.options.classActive);
9673 });
9674
9675 if (selectedRow) {
9676 selectedRow.classList.add(this.options.classActive);
9677 }
9678 } // Handle Enter or Space keydown events for selecting <label> rows
9679
9680 }, {
9681 key: "_handleKeydownChecked",
9682 value: function _handleKeydownChecked(evt) {
9683 var _this3 = this;
9684
9685 evt.preventDefault(); // prevent spacebar from scrolling page
9686
9687 var selectedRow = eventMatches(evt, this.options.selectorRow);
9688 toArray$b(this.element.querySelectorAll(this.options.selectorRow)).forEach(function (row) {
9689 return row.classList.remove(_this3.options.classActive);
9690 });
9691
9692 if (selectedRow) {
9693 selectedRow.classList.add(this.options.classActive);
9694 var input = selectedRow.querySelector(this.options.selectorListInput(selectedRow.getAttribute('for'))) || selectedRow.querySelector('input');
9695 input.checked = true;
9696 }
9697 } // Handle up and down keydown events for selecting <label> rows
9698
9699 }, {
9700 key: "_handleKeydownArrow",
9701 value: function _handleKeydownArrow(evt) {
9702 var _this4 = this;
9703
9704 evt.preventDefault(); // prevent arrow keys from scrolling
9705
9706 var selectedRow = eventMatches(evt, this.options.selectorRow);
9707
9708 var direction = this._direction(evt);
9709
9710 if (direction && selectedRow !== undefined) {
9711 var rows = toArray$b(this.element.querySelectorAll(this.options.selectorRow));
9712 rows.forEach(function (row) {
9713 return row.classList.remove(_this4.options.classActive);
9714 });
9715 var firstIndex = 0;
9716
9717 var nextIndex = this._nextIndex(rows, selectedRow, direction);
9718
9719 var lastIndex = rows.length - 1;
9720
9721 var getSelectedIndex = function getSelectedIndex() {
9722 switch (nextIndex) {
9723 case -1:
9724 return lastIndex;
9725
9726 case rows.length:
9727 return firstIndex;
9728
9729 default:
9730 return nextIndex;
9731 }
9732 };
9733
9734 var selectedIndex = getSelectedIndex();
9735 rows[selectedIndex].classList.add(this.options.classActive);
9736 rows[selectedIndex].focus();
9737
9738 this._handleInputChecked(selectedIndex);
9739 }
9740 }
9741 }], [{
9742 key: "options",
9743 get: function get() {
9744 var prefix = settings_1.prefix;
9745 return {
9746 selectorInit: '[data-structured-list]',
9747 selectorRow: "[data-structured-list] .".concat(prefix, "--structured-list-tbody > label.").concat(prefix, "--structured-list-row"),
9748 selectorListInput: function selectorListInput(id) {
9749 return "#".concat(id, ".").concat(prefix, "--structured-list-input");
9750 },
9751 classActive: "".concat(prefix, "--structured-list-row--selected")
9752 };
9753 }
9754 }]);
9755
9756 return StructuredList;
9757 }(mixin(createComponent, initComponentBySearch, handles));
9758
9759 _defineProperty(StructuredList, "components",
9760 /* #__PURE_CLASS_PROPERTY__ */
9761 new WeakMap());
9762
9763 var Slider =
9764 /*#__PURE__*/
9765 function (_mixin) {
9766 _inherits(Slider, _mixin);
9767
9768 /**
9769 * Slider.
9770 * @extends CreateComponent
9771 * @extends InitComponentBySearch
9772 * @extends Handles
9773 * @param {HTMLElement} element The element working as an slider.
9774 */
9775 function Slider(element, options) {
9776 var _this;
9777
9778 _classCallCheck(this, Slider);
9779
9780 _this = _possibleConstructorReturn(this, _getPrototypeOf(Slider).call(this, element, options));
9781
9782 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, detail, callback) {
9783 callback();
9784 });
9785
9786 _this.sliderActive = false;
9787 _this.dragging = false;
9788 _this.track = _this.element.querySelector(_this.options.selectorTrack);
9789 _this.filledTrack = _this.element.querySelector(_this.options.selectorFilledTrack);
9790 _this.thumb = _this.element.querySelector(_this.options.selectorThumb);
9791 _this.input = _this.element.querySelector(_this.options.selectorInput);
9792
9793 if (_this.element.dataset.sliderInputBox) {
9794 _this.boundInput = _this.element.ownerDocument.querySelector(_this.element.dataset.sliderInputBox);
9795
9796 _this._updateInput();
9797
9798 _this.manage(on(_this.boundInput, 'change', function (evt) {
9799 _this.setValue(evt.target.value);
9800 }));
9801
9802 _this.manage(on(_this.boundInput, 'focus', function (evt) {
9803 evt.target.select();
9804 })); // workaround for safari
9805
9806
9807 _this.manage(on(_this.boundInput, 'mouseup', function (evt) {
9808 evt.preventDefault();
9809 }));
9810 }
9811
9812 _this._updatePosition();
9813
9814 _this.manage(on(_this.thumb, 'mousedown', function () {
9815 _this.sliderActive = true;
9816 }));
9817
9818 _this.manage(on(_this.element.ownerDocument, 'mouseup', function () {
9819 _this.sliderActive = false;
9820 }));
9821
9822 _this.manage(on(_this.element.ownerDocument, 'mousemove', function (evt) {
9823 var disabled = _this.element.classList.contains(_this.options.classDisabled);
9824
9825 if (_this.sliderActive === true && !disabled) {
9826 _this._updatePosition(evt);
9827 }
9828 }));
9829
9830 _this.manage(on(_this.thumb, 'keydown', function (evt) {
9831 var disabled = _this.element.classList.contains(_this.options.classDisabled);
9832
9833 if (!disabled) {
9834 _this._updatePosition(evt);
9835 }
9836 }));
9837
9838 _this.manage(on(_this.track, 'click', function (evt) {
9839 var disabled = _this.element.classList.contains(_this.options.classDisabled);
9840
9841 if (!disabled) {
9842 _this._updatePosition(evt);
9843 }
9844 }));
9845
9846 return _this;
9847 }
9848
9849 _createClass(Slider, [{
9850 key: "_updatePosition",
9851 value: function _updatePosition(evt) {
9852 var _this2 = this;
9853
9854 var _this$_calcValue = this._calcValue(evt),
9855 left = _this$_calcValue.left,
9856 newValue = _this$_calcValue.newValue;
9857
9858 if (this.dragging) {
9859 return;
9860 }
9861
9862 this.dragging = true;
9863 requestAnimationFrame(function () {
9864 _this2.dragging = false;
9865 _this2.thumb.style.left = "".concat(left, "%");
9866 _this2.filledTrack.style.transform = "translate(0%, -50%) scaleX(".concat(left / 100, ")");
9867 _this2.input.value = newValue;
9868
9869 _this2._updateInput();
9870
9871 _this2.changeState('slider-value-change', {
9872 value: newValue
9873 });
9874 });
9875 }
9876 }, {
9877 key: "_calcValue",
9878 value: function _calcValue(evt) {
9879 var _this$getInputProps = this.getInputProps(),
9880 value = _this$getInputProps.value,
9881 min = _this$getInputProps.min,
9882 max = _this$getInputProps.max,
9883 step = _this$getInputProps.step;
9884
9885 var range = max - min;
9886 var valuePercentage = (value - min) / range * 100;
9887 var left;
9888 var newValue;
9889 left = valuePercentage;
9890 newValue = value;
9891
9892 if (evt) {
9893 var type = evt.type;
9894
9895 if (type === 'keydown') {
9896 var direction = {
9897 40: -1,
9898 // decreasing
9899 37: -1,
9900 // decreasing
9901 38: 1,
9902 // increasing
9903 39: 1 // increasing
9904
9905 }[evt.which];
9906
9907 if (direction !== undefined) {
9908 var multiplier = evt.shiftKey === true ? range / step / this.options.stepMultiplier : 1;
9909 var stepMultiplied = step * multiplier;
9910 var stepSize = stepMultiplied / range * 100;
9911 left = valuePercentage + stepSize * direction;
9912 newValue = Number(value) + stepMultiplied * direction;
9913 }
9914 }
9915
9916 if (type === 'mousemove' || type === 'click') {
9917 if (type === 'click') {
9918 this.element.querySelector(this.options.selectorThumb).classList.add(this.options.classThumbClicked);
9919 } else {
9920 this.element.querySelector(this.options.selectorThumb).classList.remove(this.options.classThumbClicked);
9921 }
9922
9923 var track = this.track.getBoundingClientRect();
9924 var unrounded = (evt.clientX - track.left) / track.width;
9925 var rounded = Math.round(range * unrounded / step) * step;
9926 left = rounded / range * 100;
9927 newValue = rounded + min;
9928 }
9929 }
9930
9931 if (newValue <= Number(min)) {
9932 left = 0;
9933 newValue = min;
9934 }
9935
9936 if (newValue >= Number(max)) {
9937 left = 100;
9938 newValue = max;
9939 }
9940
9941 return {
9942 left: left,
9943 newValue: newValue
9944 };
9945 }
9946 }, {
9947 key: "_updateInput",
9948 value: function _updateInput() {
9949 if (this.boundInput) {
9950 this.boundInput.value = this.input.value;
9951 }
9952 }
9953 }, {
9954 key: "getInputProps",
9955 value: function getInputProps() {
9956 var values = {
9957 value: Number(this.input.value),
9958 min: Number(this.input.min),
9959 max: Number(this.input.max),
9960 step: this.input.step ? Number(this.input.step) : 1
9961 };
9962 return values;
9963 }
9964 }, {
9965 key: "setValue",
9966 value: function setValue(value) {
9967 this.input.value = value;
9968
9969 this._updatePosition();
9970 }
9971 }, {
9972 key: "stepUp",
9973 value: function stepUp() {
9974 this.input.stepUp();
9975
9976 this._updatePosition();
9977 }
9978 }, {
9979 key: "stepDown",
9980 value: function stepDown() {
9981 this.input.stepDown();
9982
9983 this._updatePosition();
9984 }
9985 /**
9986 * The map associating DOM element and Slider UI instance.
9987 * @type {WeakMap}
9988 */
9989
9990 }], [{
9991 key: "options",
9992
9993 /**
9994 * The component options.
9995 * If `options` is specified in the constructor,
9996 * properties in this object are overriden for the instance being created.
9997 * @property {string} selectorInit The CSS selector to find slider instances.
9998 */
9999 get: function get() {
10000 var prefix = settings_1.prefix;
10001 return {
10002 selectorInit: '[data-slider]',
10003 selectorTrack: ".".concat(prefix, "--slider__track"),
10004 selectorFilledTrack: ".".concat(prefix, "--slider__filled-track"),
10005 selectorThumb: ".".concat(prefix, "--slider__thumb"),
10006 selectorInput: ".".concat(prefix, "--slider__input"),
10007 classDisabled: "".concat(prefix, "--slider--disabled"),
10008 classThumbClicked: "".concat(prefix, "--slider__thumb--clicked"),
10009 eventBeforeSliderValueChange: 'slider-before-value-change',
10010 eventAfterSliderValueChange: 'slider-after-value-change',
10011 stepMultiplier: 4
10012 };
10013 }
10014 }]);
10015
10016 return Slider;
10017 }(mixin(createComponent, initComponentBySearch, eventedState, handles));
10018
10019 _defineProperty(Slider, "components",
10020 /* #__PURE_CLASS_PROPERTY__ */
10021 new WeakMap());
10022
10023 var Tile =
10024 /*#__PURE__*/
10025 function (_mixin) {
10026 _inherits(Tile, _mixin);
10027
10028 /**
10029 * Tile.
10030 * @extends CreateComponent
10031 * @extends InitComponentBySearch
10032 * @param {HTMLElement} element The element working as an Tile.
10033 */
10034 function Tile(element, options) {
10035 var _this;
10036
10037 _classCallCheck(this, Tile);
10038
10039 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tile).call(this, element, options));
10040
10041 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getClass", function (type) {
10042 var typeObj = {
10043 expandable: _this.options.classExpandedTile,
10044 clickable: _this.options.classClickableTile,
10045 selectable: _this.options.classSelectableTile
10046 };
10047 return typeObj[type];
10048 });
10049
10050 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_hookActions", function (tileClass) {
10051 var isExpandable = _this.tileType === 'expandable';
10052
10053 if (isExpandable) {
10054 var aboveTheFold = _this.element.querySelector(_this.options.selectorAboveTheFold);
10055
10056 var getStyle = _this.element.ownerDocument.defaultView.getComputedStyle(_this.element, null);
10057
10058 var tilePaddingTop = parseInt(getStyle.getPropertyValue('padding-top'), 10);
10059 var tilePaddingBottom = parseInt(getStyle.getPropertyValue('padding-bottom'), 10);
10060 var tilePadding = tilePaddingTop + tilePaddingBottom;
10061
10062 if (aboveTheFold) {
10063 _this.tileHeight = _this.element.getBoundingClientRect().height;
10064 _this.atfHeight = aboveTheFold.getBoundingClientRect().height + tilePadding;
10065 _this.element.style.maxHeight = "".concat(_this.atfHeight, "px");
10066 }
10067
10068 if (_this.element.classList.contains(_this.options.classExpandedTile)) {
10069 _this._setTileHeight();
10070 }
10071 }
10072
10073 _this.element.addEventListener('click', function (evt) {
10074 var input = eventMatches(evt, _this.options.selectorTileInput);
10075
10076 if (!input) {
10077 _this.element.classList.toggle(tileClass);
10078 }
10079
10080 if (isExpandable) {
10081 _this._setTileHeight();
10082 }
10083 });
10084
10085 _this.element.addEventListener('keydown', function (evt) {
10086 var input = _this.element.querySelector(_this.options.selectorTileInput);
10087
10088 if (input) {
10089 if (evt.which === 13 || evt.which === 32) {
10090 if (!isExpandable) {
10091 _this.element.classList.toggle(tileClass);
10092
10093 input.checked = !input.checked;
10094 }
10095 }
10096 }
10097 });
10098 });
10099
10100 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setTileHeight", function () {
10101 var isExpanded = _this.element.classList.contains(_this.options.classExpandedTile);
10102
10103 _this.element.style.maxHeight = isExpanded ? "".concat(_this.tileHeight, "px") : "".concat(_this.atfHeight, "px");
10104 });
10105
10106 _this.tileType = _this.element.dataset.tile;
10107 _this.tileHeight = 0; // Tracks expandable tile height
10108
10109 _this.atfHeight = 0; // Tracks above the fold height
10110
10111 _this._hookActions(_this._getClass(_this.tileType));
10112
10113 return _this;
10114 }
10115
10116 _createClass(Tile, [{
10117 key: "release",
10118 value: function release() {
10119 _get(_getPrototypeOf(Tile.prototype), "release", this).call(this);
10120 }
10121 /**
10122 * The map associating DOM element and Tile UI instance.
10123 * @type {WeakMap}
10124 */
10125
10126 }], [{
10127 key: "options",
10128
10129 /**
10130 * The component options.
10131 * If `options` is specified in the constructor,
10132 * properties in this object are overriden for the instance being created.
10133 * @property {string} selectorInit The CSS selector to find Tile instances.
10134 */
10135 get: function get$$1() {
10136 var prefix = settings_1.prefix;
10137 return {
10138 selectorInit: '[data-tile]',
10139 selectorAboveTheFold: '[data-tile-atf]',
10140 selectorTileInput: '[data-tile-input]',
10141 classExpandedTile: "".concat(prefix, "--tile--is-expanded"),
10142 classClickableTile: "".concat(prefix, "--tile--is-clicked"),
10143 classSelectableTile: "".concat(prefix, "--tile--is-selected")
10144 };
10145 }
10146 }]);
10147
10148 return Tile;
10149 }(mixin(createComponent, initComponentBySearch));
10150
10151 _defineProperty(Tile, "components",
10152 /* #__PURE_CLASS_PROPERTY__ */
10153 new WeakMap());
10154
10155 var Carousel =
10156 /*#__PURE__*/
10157 function (_mixin) {
10158 _inherits(Carousel, _mixin);
10159
10160 /**
10161 * Carousel.
10162 * @extends CreateComponent
10163 * @extends InitComponentBySearch
10164 * @param {HTMLElement} element The element working as an carousel.
10165 */
10166 function Carousel(element, options) {
10167 var _this;
10168
10169 _classCallCheck(this, Carousel);
10170
10171 _this = _possibleConstructorReturn(this, _getPrototypeOf(Carousel).call(this, element, options));
10172
10173 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleClick", function (evt) {
10174 if (evt.target.matches(_this.options.selectorScrollRight)) {
10175 _this.sideScroll('right');
10176 } else {
10177 _this.sideScroll('left');
10178 }
10179 });
10180
10181 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "sideScroll", function (direction) {
10182 var filmstripWidth = _this.filmstrip.getBoundingClientRect().width;
10183
10184 var itemWidth = _this.carouselItem.getBoundingClientRect().width + 20;
10185 var re = /\.*translateX\((.*)px\)/i;
10186 var translateXValue = _this.filmstrip.style.transform ? Number(_this.filmstrip.style.transform.split(re)[1]) : 0;
10187 var directionValue = direction === 'right' ? -1 : 1;
10188 var itemWidthDirection = itemWidth * directionValue;
10189 var newTranslateValue = itemWidthDirection + translateXValue;
10190
10191 if (newTranslateValue > 0) {
10192 newTranslateValue = 0;
10193 }
10194
10195 if (newTranslateValue < filmstripWidth * -1) {
10196 newTranslateValue = filmstripWidth * -1;
10197 }
10198
10199 _this.filmstrip.style.transform = "translateX(".concat(newTranslateValue, "px)");
10200 });
10201
10202 _this.filmstrip = _this.element.querySelector(_this.options.selectorFilmstrip);
10203 _this.carouselItem = _this.element.querySelector(_this.options.selectorCarouselItem);
10204
10205 _this.element.addEventListener('click', function (evt) {
10206 return _this.handleClick(evt);
10207 });
10208
10209 return _this;
10210 }
10211
10212 _createClass(Carousel, null, [{
10213 key: "options",
10214 get: function get() {
10215 var prefix = settings_1.prefix;
10216 return {
10217 selectorInit: '[data-carousel]',
10218 selectorFilmstrip: ".".concat(prefix, "--filmstrip"),
10219 selectorScrollRight: '[data-scroll-right]',
10220 selectorScrollLeft: '[data-scroll-left]',
10221 selectorCarouselBtn: ".".concat(prefix, "--carousel__btn"),
10222 selectorCarouselItem: ".".concat(prefix, "--carousel__item")
10223 };
10224 }
10225 /**
10226 * The map associating DOM element and accordion UI instance.
10227 * @type {WeakMap}
10228 */
10229
10230 }]);
10231
10232 return Carousel;
10233 }(mixin(createComponent, initComponentBySearch));
10234
10235 _defineProperty(Carousel, "components",
10236 /* #__PURE_CLASS_PROPERTY__ */
10237 new WeakMap());
10238
10239 var carousel = !breakingChangesX ? Carousel : removedComponent('Carousel');
10240
10241 var toArray$c = function toArray(arrayLike) {
10242 return Array.prototype.slice.call(arrayLike);
10243 };
10244
10245 var Lightbox =
10246 /*#__PURE__*/
10247 function (_mixin) {
10248 _inherits(Lightbox, _mixin);
10249
10250 function Lightbox(element, options) {
10251 var _this;
10252
10253 _classCallCheck(this, Lightbox);
10254
10255 _this = _possibleConstructorReturn(this, _getPrototypeOf(Lightbox).call(this, element, options));
10256
10257 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "showLightbox", function (evt) {
10258 if (!evt.detail.launchingElement.dataset.carouselItemIndex) {
10259 throw new Error('launchingElement must have carouselItemIndex data attribute to indicated what item to display');
10260 }
10261
10262 _this.activeIndex = evt.detail.launchingElement.dataset.carouselItemIndex;
10263
10264 _this.updateSlide();
10265 });
10266
10267 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleClick", function (evt) {
10268 if (evt.target.matches(_this.options.selectorScrollRight)) {
10269 if (_this.activeIndex < _this.totalSlides) {
10270 _this.activeIndex++;
10271
10272 _this.updateSlide();
10273 }
10274 }
10275
10276 if (evt.target.matches(_this.options.selectorScrollLeft)) {
10277 if (_this.activeIndex > 0) {
10278 _this.activeIndex--;
10279
10280 _this.updateSlide();
10281 }
10282 }
10283 });
10284
10285 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "updateSlide", function () {
10286 var items = toArray$c(_this.element.querySelectorAll(_this.options.selectorLightboxItem));
10287
10288 if (_this.activeIndex < 0 || _this.activeIndex >= items.length) {
10289 throw new RangeError('carouselItemIndex data attribute must be in range of lightbox items length');
10290 }
10291
10292 items.forEach(function (item) {
10293 return item.classList.remove(_this.options.classActiveItem);
10294 });
10295
10296 items[_this.activeIndex].classList.add(_this.options.classActiveItem);
10297 });
10298
10299 _this.activeIndex = _this.element.dataset.lightboxIndex;
10300 _this.totalSlides = _this.element.querySelectorAll(_this.options.selectorLightboxItem).length - 1;
10301
10302 _this.updateSlide();
10303
10304 _this.element.addEventListener('click', function (evt) {
10305 return _this.handleClick(evt);
10306 });
10307
10308 _this.element.parentNode.addEventListener('modal-beingshown', function (evt) {
10309 return _this.showLightbox(evt);
10310 });
10311
10312 return _this;
10313 }
10314
10315 _createClass(Lightbox, null, [{
10316 key: "options",
10317 get: function get() {
10318 var prefix = settings_1.prefix;
10319 return {
10320 selectorInit: '[data-lightbox]',
10321 selectorScrollRight: '[data-scroll-right]',
10322 selectorScrollLeft: '[data-scroll-left]',
10323 selectorLightboxItem: ".".concat(prefix, "--lightbox__item"),
10324 classActiveItem: "".concat(prefix, "--lightbox__item--shown")
10325 };
10326 }
10327 /**
10328 * The map associating DOM element and accordion UI instance.
10329 * @type {WeakMap}
10330 */
10331
10332 }]);
10333
10334 return Lightbox;
10335 }(mixin(createComponent, initComponentBySearch));
10336
10337 _defineProperty(Lightbox, "components",
10338 /* #__PURE_CLASS_PROPERTY__ */
10339 new WeakMap());
10340
10341 var lightbox = !breakingChangesX ? Lightbox : removedComponent('Lightbox');
10342
10343 var CodeSnippet =
10344 /*#__PURE__*/
10345 function (_mixin) {
10346 _inherits(CodeSnippet, _mixin);
10347
10348 /**
10349 * CodeSnippet UI.
10350 * @extends CreateComponent
10351 * @extends InitComponentBySearch
10352 * @extends Handles
10353 * @param {HTMLElement} element The element working as a CodeSnippet UI.
10354 */
10355 function CodeSnippet(element, options) {
10356 var _this;
10357
10358 _classCallCheck(this, CodeSnippet);
10359
10360 _this = _possibleConstructorReturn(this, _getPrototypeOf(CodeSnippet).call(this, element, options));
10361
10362 _this._initCodeSnippet();
10363
10364 _this.element.querySelector(_this.options.classExpandBtn).addEventListener('click', function (evt) {
10365 return _this._handleClick(evt);
10366 });
10367
10368 return _this;
10369 }
10370
10371 _createClass(CodeSnippet, [{
10372 key: "_handleClick",
10373 value: function _handleClick() {
10374 var expandBtn = this.element.querySelector(this.options.classExpandText);
10375 this.element.classList.toggle(this.options.classExpanded);
10376
10377 if (this.element.classList.contains(this.options.classExpanded)) {
10378 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowLessText);
10379 } else {
10380 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowMoreText);
10381 }
10382 }
10383 }, {
10384 key: "_initCodeSnippet",
10385 value: function _initCodeSnippet() {
10386 var expandBtn = this.element.querySelector(this.options.classExpandText);
10387
10388 if (!expandBtn) {
10389 throw new TypeError('Cannot find the expand button.');
10390 }
10391
10392 expandBtn.textContent = expandBtn.getAttribute(this.options.attribShowMoreText);
10393
10394 if (this.element.offsetHeight < this.options.minHeight) {
10395 this.element.classList.add(this.options.classHideExpand);
10396 }
10397 }
10398 /**
10399 * The map associating DOM element and code snippet UI instance.
10400 * @member CodeSnippet.components
10401 * @type {WeakMap}
10402 */
10403
10404 }], [{
10405 key: "options",
10406
10407 /**
10408 * The component options.
10409 * If `options` is specified in the constructor, {@linkcode CodeSnippet.create .create()},
10410 * or {@linkcode CodeSnippet.init .init()},
10411 * properties in this object are overriden for the instance being create and how {@linkcode CodeSnippet.init .init()} works.
10412 * @member CodeSnippet.options
10413 * @type {Object}
10414 * @property {string} selectorInit The data attribute to find code snippet UIs.
10415 */
10416 get: function get() {
10417 var prefix = settings_1.prefix;
10418 return {
10419 selectorInit: '[data-code-snippet]',
10420 attribShowMoreText: 'data-show-more-text',
10421 attribShowLessText: 'data-show-less-text',
10422 minHeight: 288,
10423 classExpanded: "".concat(prefix, "--snippet--expand"),
10424 classExpandBtn: ".".concat(prefix, "--snippet-btn--expand"),
10425 classExpandText: ".".concat(prefix, "--snippet-btn--text"),
10426 classHideExpand: "".concat(prefix, "--snippet-btn--expand--hide")
10427 };
10428 }
10429 }]);
10430
10431 return CodeSnippet;
10432 }(mixin(createComponent, initComponentBySearch, handles));
10433
10434 _defineProperty(CodeSnippet, "components",
10435 /* #__PURE_CLASS_PROPERTY__ */
10436 new WeakMap());
10437
10438 var TextInput =
10439 /*#__PURE__*/
10440 function (_mixin) {
10441 _inherits(TextInput, _mixin);
10442
10443 /**
10444 * Text Input.
10445 * @extends CreateComponent
10446 * @extends InitComponentBySearch
10447 * @extends Handles
10448 * @param {HTMLElement} element - The element functioning as a text field.
10449 */
10450 function TextInput(_element, options) {
10451 var _this;
10452
10453 _classCallCheck(this, TextInput);
10454
10455 _this = _possibleConstructorReturn(this, _getPrototypeOf(TextInput).call(this, _element, options));
10456
10457 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setIconVisibility", function (_ref) {
10458 var iconVisibilityOn = _ref.iconVisibilityOn,
10459 iconVisibilityOff = _ref.iconVisibilityOff,
10460 passwordIsVisible = _ref.passwordIsVisible,
10461 selectorPasswordVisibilityButton = _ref.selectorPasswordVisibilityButton;
10462
10463 if (passwordIsVisible) {
10464 iconVisibilityOn.setAttribute('hidden', true);
10465 iconVisibilityOff.removeAttribute('hidden');
10466 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Hide password');
10467 return;
10468 }
10469
10470 iconVisibilityOn.removeAttribute('hidden');
10471 iconVisibilityOff.setAttribute('hidden', true);
10472 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Show password');
10473 });
10474
10475 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_toggle", function (_ref2) {
10476 var element = _ref2.element,
10477 button = _ref2.button;
10478 // toggle action must come before querying the classList
10479 element.classList.toggle(_this.options.passwordIsVisible);
10480 var passwordIsVisible = element.classList.contains(_this.options.passwordIsVisible);
10481 var iconVisibilityOn = button.querySelector(_this.options.svgIconVisibilityOn);
10482 var iconVisibilityOff = button.querySelector(_this.options.svgIconVisibilityOff);
10483 var input = element.querySelector(_this.options.selectorPasswordField);
10484 var selectorPasswordVisibilityButton = element.querySelector(_this.options.selectorPasswordVisibilityButton);
10485
10486 _this._setIconVisibility({
10487 iconVisibilityOn: iconVisibilityOn,
10488 iconVisibilityOff: iconVisibilityOff,
10489 passwordIsVisible: passwordIsVisible,
10490 selectorPasswordVisibilityButton: selectorPasswordVisibilityButton
10491 });
10492
10493 input.type = passwordIsVisible ? 'text' : 'password';
10494 });
10495
10496 _this.manage(on(_this.element, 'click', function (event) {
10497 var toggleVisibilityButton = eventMatches(event, _this.options.selectorPasswordVisibilityButton);
10498
10499 if (toggleVisibilityButton) {
10500 _this._toggle({
10501 element: _element,
10502 button: toggleVisibilityButton
10503 });
10504 }
10505 }));
10506
10507 return _this;
10508 }
10509 /**
10510 *
10511 * @param {Object} obj - Object containing selectors and visibility status
10512 * @param {HTMLElement} obj.iconVisibilityOn - The element functioning as
10513 * the SVG icon for visibility on
10514 * @param {HTMLElement} obj.iconVisibilityOff - The element functioning as
10515 * the SVG icon for visibility off
10516 * @param {boolean} obj.passwordIsVisible - The visibility of the password in the
10517 * input field
10518 */
10519
10520
10521 _createClass(TextInput, null, [{
10522 key: "options",
10523
10524 /**
10525 * The component options.
10526 *
10527 * If `options` is specified in the constructor,
10528 * {@linkcode TextInput.create .create()},
10529 * or {@linkcode TextInput.init .init()},
10530 * properties in this object are overriden for the instance being
10531 * created and how {@linkcode TextInput.init .init()} works.
10532 * @property {string} selectorInit The CSS selector to find text input UIs.
10533 */
10534 get: function get() {
10535 var prefix = settings_1.prefix;
10536 return {
10537 selectorInit: '[data-text-input]',
10538 selectorPasswordField: ".".concat(prefix, "--text-input[data-toggle-password-visibility]"),
10539 selectorPasswordVisibilityButton: ".".concat(prefix, "--text-input--password__visibility"),
10540 passwordIsVisible: "".concat(prefix, "--text-input--password-visible"),
10541 svgIconVisibilityOn: "svg.".concat(prefix, "--icon--visibility-on"),
10542 svgIconVisibilityOff: "svg.".concat(prefix, "--icon--visibility-off")
10543 };
10544 }
10545 /**
10546 * The map associating DOM element and text input UI instance.
10547 * @type {WeakMap}
10548 */
10549
10550 }]);
10551
10552 return TextInput;
10553 }(mixin(createComponent, initComponentBySearch, handles));
10554
10555 _defineProperty(TextInput, "components",
10556 /* #__PURE_CLASS_PROPERTY__ */
10557 new WeakMap());
10558
10559 var prefix = settings_1.prefix;
10560
10561 var SideNav =
10562 /*#__PURE__*/
10563 function (_mixin) {
10564 _inherits(SideNav, _mixin);
10565
10566 /**
10567 * The map associating DOM element and copy button UI instance.
10568 * @member SideNav.components
10569 * @type {WeakMap}
10570 */
10571 function SideNav(element, options) {
10572 var _this;
10573
10574 _classCallCheck(this, SideNav);
10575
10576 _this = _possibleConstructorReturn(this, _getPrototypeOf(SideNav).call(this, element, options));
10577
10578 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleClick", function (evt) {
10579 var matchesToggle = eventMatches(evt, _this.options.selectorSideNavToggle);
10580 var matchesNavSubmenu = eventMatches(evt, _this.options.selectorSideNavSubmenu);
10581 var matchesSideNavLink = eventMatches(evt, _this.options.selectorSideNavLink);
10582
10583 if (!matchesToggle && !matchesNavSubmenu && !matchesSideNavLink) {
10584 return;
10585 }
10586
10587 if (matchesToggle) {
10588 _this.changeState(!_this.isNavExpanded() ? _this.constructor.state.EXPANDED : _this.constructor.state.COLLAPSED);
10589
10590 return;
10591 }
10592
10593 if (matchesNavSubmenu) {
10594 var isSubmenuExpanded = matchesNavSubmenu.getAttribute('aria-expanded') === 'true';
10595 matchesNavSubmenu.setAttribute('aria-expanded', "".concat(!isSubmenuExpanded));
10596 return;
10597 }
10598
10599 if (matchesSideNavLink) {
10600 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorSideNavLinkCurrent)).forEach(function (el) {
10601 el.classList.remove(_this.options.classSideNavItemActive, _this.options.classSideNavLinkCurrent);
10602 el.removeAttribute('aria-current');
10603 });
10604
10605 matchesSideNavLink.classList.add(_this.options.classSideNavLinkCurrent);
10606 var closestSideNavItem = matchesSideNavLink.closest(_this.options.selectorSideNavItem);
10607
10608 if (closestSideNavItem) {
10609 closestSideNavItem.classList.add(_this.options.classSideNavItemActive);
10610 }
10611 }
10612 });
10613
10614 _this.manage(on(element, 'click', _this._handleClick));
10615
10616 return _this;
10617 }
10618 /**
10619 * Enum for toggling side nav visibility
10620 * @readonly
10621 * @member SideNav.state
10622 * @type {Object}
10623 * @property {string} EXPANDED Opening/visible
10624 * @property {string} COLLAPSED Closing/hidden
10625 */
10626
10627
10628 _createClass(SideNav, [{
10629 key: "isNavExpanded",
10630
10631 /**
10632 * @returns {boolean} `true` if the nav is expanded.
10633 */
10634 value: function isNavExpanded() {
10635 return this.element.classList.contains(this.options.classSideNavExpanded);
10636 }
10637 /**
10638 * Changes the expanded/collapsed state.
10639 */
10640
10641 }, {
10642 key: "changeState",
10643 value: function changeState(state) {
10644 this.element.classList.toggle(this.options.classSideNavExpanded, state === this.constructor.state.EXPANDED);
10645 }
10646 }]);
10647
10648 return SideNav;
10649 }(mixin(createComponent, initComponentBySearch, handles));
10650
10651 _defineProperty(SideNav, "components",
10652 /* #__PURE_CLASS_PROPERTY__ */
10653 new WeakMap());
10654
10655 _defineProperty(SideNav, "state",
10656 /* #__PURE_CLASS_PROPERTY__ */
10657 {
10658 EXPANDED: 'expanded',
10659 COLLAPSED: 'collapsed'
10660 });
10661
10662 _defineProperty(SideNav, "options",
10663 /* #__PURE_CLASS_PROPERTY__ */
10664 {
10665 selectorInit: '[data-side-nav]',
10666 selectorSideNavToggle: ".".concat(prefix, "--side-nav__toggle"),
10667 selectorSideNavSubmenu: ".".concat(prefix, "--side-nav__submenu"),
10668 selectorSideNavItem: ".".concat(prefix, "--side-nav__item"),
10669 selectorSideNavLink: ".".concat(prefix, "--side-nav__link"),
10670 selectorSideNavLinkCurrent: "[aria-current=\"page\"],.".concat(prefix, "--side-nav__link--current,.").concat(prefix, "--side-nav__item--active"),
10671 classSideNavExpanded: "".concat(prefix, "--side-nav--expanded"),
10672 classSideNavItemActive: "".concat(prefix, "--side-nav__item--active"),
10673 classSideNavLinkCurrent: "".concat(prefix, "--side-nav__link--current")
10674 });
10675
10676 var forEach =
10677 /* #__PURE__ */
10678 function () {
10679 return Array.prototype.forEach;
10680 }();
10681
10682 var toArray$d = function toArray(arrayLike) {
10683 return Array.prototype.slice.call(arrayLike);
10684 };
10685
10686 var HeaderSubmenu =
10687 /*#__PURE__*/
10688 function (_mixin) {
10689 _inherits(HeaderSubmenu, _mixin);
10690
10691 function HeaderSubmenu(element, options) {
10692 var _this;
10693
10694 _classCallCheck(this, HeaderSubmenu);
10695
10696 _this = _possibleConstructorReturn(this, _getPrototypeOf(HeaderSubmenu).call(this, element, options));
10697
10698 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getAction", function (event) {
10699 var isFlyoutMenu = eventMatches(event, _this.options.selectorFlyoutMenu);
10700
10701 if (isFlyoutMenu) {
10702 return _this.constructor.actions.DELEGATE_TO_FLYOUT_MENU;
10703 }
10704
10705 switch (event.type) {
10706 case 'keydown':
10707 return {
10708 32: _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS,
10709 // space bar
10710 13: _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS,
10711 // enter
10712 27: _this.constructor.actions.CLOSE_SUBMENU // esc
10713 // possible arrow keys
10714
10715 }[event.which];
10716
10717 case 'click':
10718 return eventMatches(event, _this.options.selectorItem) ? _this.constructor.actions.CLOSE_SUBMENU : null;
10719
10720 case 'blur':
10721 case 'focusout':
10722 {
10723 var isOfSelf = _this.element.contains(event.relatedTarget);
10724
10725 return isOfSelf ? null : _this.constructor.actions.CLOSE_SUBMENU;
10726 }
10727
10728 case 'mouseenter':
10729 return _this.constructor.actions.OPEN_SUBMENU;
10730
10731 case 'mouseleave':
10732 return _this.constructor.actions.CLOSE_SUBMENU;
10733
10734 default:
10735 return null;
10736 }
10737 });
10738
10739 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_getNewState", function (action) {
10740 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
10741
10742 var isExpanded = trigger.getAttribute(_this.options.attribExpanded) === 'true';
10743
10744 switch (action) {
10745 case _this.constructor.actions.CLOSE_SUBMENU:
10746 return false;
10747
10748 case _this.constructor.actions.OPEN_SUBMENU:
10749 return true;
10750
10751 case _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS:
10752 return !isExpanded;
10753
10754 default:
10755 return isExpanded;
10756 }
10757 });
10758
10759 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_setState", function (_ref) {
10760 var shouldBeExpanded = _ref.shouldBeExpanded,
10761 shouldFocusOnOpen = _ref.shouldFocusOnOpen;
10762
10763 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
10764
10765 trigger.setAttribute(_this.options.attribExpanded, shouldBeExpanded);
10766 forEach.call(_this.element.querySelectorAll(_this.options.selectorItem), function (item) {
10767 item.tabIndex = shouldBeExpanded ? 0 : -1;
10768 }); // focus first submenu item
10769
10770 if (shouldBeExpanded && shouldFocusOnOpen) {
10771 _this.element.querySelector(_this.options.selectorItem).focus();
10772 }
10773 });
10774
10775 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
10776 var focused = _this.element.ownerDocument.activeElement;
10777 return focused.nodeType === Node.ELEMENT_NODE && focused.matches(_this.options.selectorItem) ? focused : null;
10778 });
10779
10780 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
10781 var items = toArray$d(_this.element.querySelectorAll(_this.options.selectorItem));
10782
10783 var start = _this.getCurrentNavigation() || _this.element.querySelector(_this.options.selectorItemSelected);
10784
10785 var getNextItem = function getNextItem(old) {
10786 var handleUnderflow = function handleUnderflow(index, length) {
10787 return index + (index >= 0 ? 0 : length);
10788 };
10789
10790 var handleOverflow = function handleOverflow(index, length) {
10791 return index - (index < length ? 0 : length);
10792 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
10793
10794
10795 var index = Math.max(items.indexOf(old) + direction, -1);
10796 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
10797 };
10798
10799 for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
10800 if (!current.matches(_this.options.selectorItemHidden) && !current.parentNode.matches(_this.options.selectorItemHidden) && !current.matches(_this.options.selectorItemSelected)) {
10801 current.focus();
10802 break;
10803 }
10804 }
10805 });
10806
10807 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleEvent", function (event) {
10808 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
10809
10810 if (!trigger) {
10811 return;
10812 }
10813
10814 var action = _this._getAction(event);
10815
10816 if (action) {
10817 var shouldBeExpanded = _this._getNewState(action);
10818
10819 _this._setState({
10820 shouldBeExpanded: shouldBeExpanded
10821 });
10822 }
10823 });
10824
10825 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
10826 var trigger = _this.element.querySelector(_this.options.selectorTrigger);
10827
10828 if (!trigger) {
10829 return;
10830 }
10831
10832 var action = _this._getAction(event);
10833
10834 if (event.which === 32) {
10835 event.preventDefault();
10836 }
10837
10838 switch (action) {
10839 case _this.constructor.actions.DELEGATE_TO_FLYOUT_MENU:
10840 // currently we do not have a scenario that handles flyout menu
10841 // handleFlyoutMenu
10842 break;
10843 // currently we do not have a scenario that opens a submenu on keydown
10844 // case this.constructor.actions.OPEN_SUBMENU:
10845
10846 case _this.constructor.actions.CLOSE_SUBMENU:
10847 {
10848 var shouldBeExpanded = _this._getNewState(action);
10849
10850 _this._setState({
10851 shouldBeExpanded: shouldBeExpanded
10852 });
10853
10854 break;
10855 }
10856
10857 case _this.constructor.actions.TOGGLE_SUBMENU_WITH_FOCUS:
10858 {
10859 var _shouldBeExpanded = _this._getNewState(action);
10860
10861 _this._setState({
10862 shouldBeExpanded: _shouldBeExpanded,
10863 shouldFocusOnOpen: true
10864 });
10865
10866 break;
10867 }
10868
10869 default:
10870 {
10871 var expanded = trigger.getAttribute(_this.options.attribExpanded) === 'true';
10872
10873 if (expanded) {
10874 var direction = {
10875 38: _this.constructor.NAVIGATE.BACKWARD,
10876 40: _this.constructor.NAVIGATE.FORWARD
10877 }[event.which];
10878
10879 switch (event.which) {
10880 case 35:
10881 {
10882 // end key
10883 event.preventDefault(); // prevents key from scrolling page
10884
10885 var menuItems = _this.element.querySelectorAll(_this.options.selectorItem);
10886
10887 var lastMenuItem = menuItems[menuItems.length - 1];
10888
10889 if (lastMenuItem) {
10890 lastMenuItem.focus();
10891 }
10892
10893 break;
10894 }
10895
10896 case 36:
10897 {
10898 // home key
10899 event.preventDefault(); // prevents key from scrolling page
10900
10901 var _this$element$querySe = _this.element.querySelectorAll(_this.options.selectorItem),
10902 _this$element$querySe2 = _slicedToArray(_this$element$querySe, 1),
10903 firstMenuItem = _this$element$querySe2[0];
10904
10905 if (firstMenuItem) {
10906 firstMenuItem.focus();
10907 }
10908
10909 break;
10910 }
10911
10912 case 38: // up arrow
10913
10914 case 40:
10915 // down arrow
10916 _this.navigate(direction);
10917
10918 event.preventDefault(); // prevents keys from scrolling page
10919
10920 break;
10921
10922 default:
10923 break;
10924 }
10925 }
10926
10927 break;
10928 }
10929 }
10930 });
10931
10932 var hasFocusOut = 'onfocusout' in window;
10933
10934 _this.manage(on(_this.element, hasFocusOut ? 'focusout' : 'blur', _this._handleEvent, !hasFocusOut));
10935
10936 _this.manage(on(_this.element, 'mouseenter', _this._handleEvent));
10937
10938 _this.manage(on(_this.element, 'mouseleave', _this._handleEvent));
10939
10940 _this.manage(on(_this.element, 'click', _this._handleEvent));
10941
10942 _this.manage(on(_this.element, 'keydown', _this._handleKeyDown));
10943
10944 return _this;
10945 }
10946 /**
10947 * The map associating DOM element and HeaderSubmenu instance.
10948 * @member HeaderSubmenu.components
10949 * @type {WeakMap}
10950 */
10951
10952
10953 _createClass(HeaderSubmenu, null, [{
10954 key: "options",
10955
10956 /**
10957 * The component options.
10958 * If `options` is specified in the constructor,
10959 * {@linkcode HeaderSubmenu.create .create()}, or
10960 * {@linkcode HeaderSubmenu.init .init()},
10961 * properties in this object are overriden for the instance being create and
10962 * how {@linkcode HeaderSubmenu.init .init()} works.
10963 * @member HeaderSubmenu.options
10964 * @type {Object}
10965 * @property {string} selectorInit The data attribute to find side navs.
10966 */
10967 get: function get() {
10968 var prefix = settings_1.prefix;
10969 return {
10970 selectorInit: '[data-header-submenu]',
10971 selectorTrigger: ".".concat(prefix, "--header__menu-title"),
10972 selectorItem: ".".concat(prefix, "--header__menu .").concat(prefix, "--header__menu-item"),
10973 attribExpanded: 'aria-expanded'
10974 };
10975 }
10976 /**
10977 * Enum for navigating backward/forward.
10978 * @readonly
10979 * @member HeaderSubmenu.NAVIGATE
10980 * @type {Object}
10981 * @property {number} BACKWARD Navigating backward.
10982 * @property {number} FORWARD Navigating forward.
10983 */
10984
10985 }]);
10986
10987 return HeaderSubmenu;
10988 }(mixin(createComponent, initComponentBySearch, handles));
10989
10990 _defineProperty(HeaderSubmenu, "components",
10991 /* #__PURE_CLASS_PROPERTY__ */
10992 new WeakMap());
10993
10994 _defineProperty(HeaderSubmenu, "actions",
10995 /* #__PURE_CLASS_PROPERTY__ */
10996 {
10997 CLOSE_SUBMENU: 'CLOSE_SUBMENU',
10998 OPEN_SUBMENU: 'OPEN_SUBMENU',
10999 TOGGLE_SUBMENU_WITH_FOCUS: 'TOGGLE_SUBMENU_WITH_FOCUS',
11000 DELEGATE_TO_FLYOUT_MENU: 'DELEGATE_TO_FLYOUT_MENU'
11001 });
11002
11003 _defineProperty(HeaderSubmenu, "NAVIGATE",
11004 /* #__PURE_CLASS_PROPERTY__ */
11005 {
11006 BACKWARD: -1,
11007 FORWARD: 1
11008 });
11009
11010 var toArray$e = function toArray(arrayLike) {
11011 return Array.prototype.slice.call(arrayLike);
11012 };
11013
11014 var HeaderNav =
11015 /*#__PURE__*/
11016 function (_mixin) {
11017 _inherits(HeaderNav, _mixin);
11018
11019 function HeaderNav(element, options) {
11020 var _this;
11021
11022 _classCallCheck(this, HeaderNav);
11023
11024 _this = _possibleConstructorReturn(this, _getPrototypeOf(HeaderNav).call(this, element, options));
11025
11026 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
11027 var focused = _this.element.ownerDocument.activeElement.closest(_this.options.selectorSubmenu);
11028
11029 return focused && focused.nodeType === Node.ELEMENT_NODE ? focused.querySelector(_this.options.selectorSubmenuLink) : null;
11030 });
11031
11032 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
11033 var items = toArray$e(_this.element.querySelectorAll(_this.options.selectorSubmenuLink));
11034
11035 var start = _this.getCurrentNavigation();
11036
11037 var getNextItem = function getNextItem(old) {
11038 var handleUnderflow = function handleUnderflow(index, length) {
11039 return index + (index >= 0 ? 0 : length);
11040 };
11041
11042 var handleOverflow = function handleOverflow(index, length) {
11043 return index - (index < length ? 0 : length);
11044 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
11045
11046
11047 var index = Math.max(items.indexOf(old) + direction, -1);
11048 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
11049 };
11050
11051 getNextItem(start).focus();
11052 });
11053
11054 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
11055 var keyCodes = {
11056 37: _this.constructor.NAVIGATE.BACKWARD,
11057 // left arrow
11058 39: _this.constructor.NAVIGATE.FORWARD // right arrow
11059
11060 };
11061 var keyCodeMatches = keyCodes[event.which];
11062
11063 if (keyCodeMatches) {
11064 _this.navigate(keyCodeMatches);
11065 }
11066 });
11067
11068 _this.manage(on(_this.element, 'keydown', _this._handleKeyDown));
11069
11070 return _this;
11071 }
11072 /**
11073 * The map associating DOM element and Header instance.
11074 * @member HeaderNav.components
11075 * @type {WeakMap}
11076 */
11077
11078
11079 _createClass(HeaderNav, null, [{
11080 key: "options",
11081
11082 /**
11083 * The component options.
11084 * If `options` is specified in the constructor,
11085 * {@linkcode HeaderNav.create .create()}, or
11086 * {@linkcode HeaderNav.init .init()},
11087 * properties in this object are overriden for the instance being create and
11088 * how {@linkcode HeaderNav.init .init()} works.
11089 * @member HeaderNav.options
11090 * @type {Object}
11091 * @property {string} selectorInit The data attribute to find side navs.
11092 */
11093 get: function get() {
11094 var prefix = settings_1.prefix;
11095 return {
11096 selectorInit: '[data-header-nav]',
11097 selectorNavKind: '[data-header-nav-kind]',
11098 selectorSubmenu: ".".concat(prefix, "--header__submenu"),
11099 selectorSubmenuLink: ".".concat(prefix, "--header__menu-title"),
11100 selectorSubmenuItem: ".".concat(prefix, "--header__menu-title > .").concat(prefix, "--header__menu-item")
11101 };
11102 }
11103 /**
11104 * Enum for navigating backward/forward.
11105 * @readonly
11106 * @member Header.NAVIGATE
11107 * @type {Object}
11108 * @property {number} BACKWARD Navigating backward.
11109 * @property {number} FORWARD Navigating forward.
11110 */
11111
11112 }]);
11113
11114 return HeaderNav;
11115 }(mixin(createComponent, initComponentBySearch, handles));
11116
11117 _defineProperty(HeaderNav, "components",
11118 /* #__PURE_CLASS_PROPERTY__ */
11119 new WeakMap());
11120
11121 _defineProperty(HeaderNav, "NAVIGATE",
11122 /* #__PURE_CLASS_PROPERTY__ */
11123 {
11124 BACKWARD: -1,
11125 FORWARD: 1
11126 });
11127
11128 var NavigationMenuPanel =
11129 /*#__PURE__*/
11130 function (_mixin) {
11131 _inherits(NavigationMenuPanel, _mixin);
11132
11133 function NavigationMenuPanel() {
11134 var _getPrototypeOf2;
11135
11136 var _this;
11137
11138 _classCallCheck(this, NavigationMenuPanel);
11139
11140 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
11141 args[_key] = arguments[_key];
11142 }
11143
11144 _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(NavigationMenuPanel)).call.apply(_getPrototypeOf2, [this].concat(args)));
11145
11146 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "createdByLauncher", function (event) {
11147 var isExpanded = !_this.element.hasAttribute('hidden');
11148 var newState = isExpanded ? 'collapsed' : 'expanded';
11149 _this.triggerButton = event.delegateTarget;
11150
11151 _this.changeState(newState);
11152 });
11153
11154 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "shouldStateBeChanged", function (state) {
11155 return state === 'expanded' === _this.element.hasAttribute('hidden');
11156 });
11157
11158 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
11159 toggleAttribute(_this.element, 'hidden', state !== 'expanded');
11160
11161 if (_this.triggerButton) {
11162 if (state === 'expanded') {
11163 var focusableMenuItems = _this.element.querySelector(_this.options.selectorFocusableMenuItem);
11164
11165 if (focusableMenuItems) {
11166 focusableMenuItems.focus();
11167 }
11168 }
11169
11170 var label = state === 'expanded' ? _this.triggerButton.getAttribute(_this.options.attribLabelCollapse) : _this.triggerButton.getAttribute(_this.options.attribLabelExpand);
11171
11172 _this.triggerButton.classList.toggle(_this.options.classNavigationMenuPanelHeaderActionActive, state === 'expanded');
11173
11174 _this.triggerButton.setAttribute('aria-label', label);
11175
11176 _this.triggerButton.setAttribute('title', label);
11177 }
11178
11179 callback();
11180 });
11181
11182 return _this;
11183 }
11184
11185 _createClass(NavigationMenuPanel, null, [{
11186 key: "options",
11187
11188 /**
11189 * The component options.
11190 * If `options` is specified in the constructor,
11191 * {@linkcode NavigationMenuPanel.create .create()}, or
11192 * {@linkcode NavigationMenuPanel.init .init()},
11193 * properties in this object are overriden for the instance being create and
11194 * how {@linkcode NavigationMenuPanel.init .init()} works.
11195 * @member NavigationMenuPanel.options
11196 * @type {Object}
11197 * @property {string} selectorInit The CSS class to find popup navs.
11198 * @property {string} attribInitTarget The attribute name in the launcher buttons to find target popup nav.
11199 * @property {string[]} initEventNames The events that the component will handles
11200 */
11201 get: function get() {
11202 var prefix = settings_1.prefix;
11203 return {
11204 initEventNames: ['click'],
11205 eventBeforeExpanded: 'navigation-menu-being-expanded',
11206 eventAfterExpanded: 'navigation-menu-expanded',
11207 eventBeforeCollapsed: 'navigation-menu-being-collapsed',
11208 eventAfterCollapsed: 'navigation-menu-collapsed',
11209 selectorFocusableMenuItem: ".".concat(prefix, "--navigation__category-toggle, .").concat(prefix, "--navigation-link"),
11210 classNavigationMenuPanelHeaderActionActive: "".concat(prefix, "--header__action--active"),
11211 attribLabelExpand: 'data-navigation-menu-panel-label-expand',
11212 attribLabelCollapse: 'data-navigation-menu-panel-label-collapse'
11213 };
11214 }
11215 }]);
11216
11217 return NavigationMenuPanel;
11218 }(mixin(createComponent, initComponentByLauncher, exports$1, handles, eventedState));
11219
11220 _defineProperty(NavigationMenuPanel, "components",
11221 /* #__PURE_CLASS_PROPERTY__ */
11222 new WeakMap());
11223
11224 var NavigationMenu =
11225 /*#__PURE__*/
11226 function (_NavigationMenuPanel) {
11227 _inherits(NavigationMenu, _NavigationMenuPanel);
11228
11229 /**
11230 * A navigation menu
11231 * @extends NavigationMenuPanel
11232 * @param {HTMLElement} element The element working as a selector.
11233 * @param {Object} [options] The component options.
11234 * @param {string} [options.selectorInit] The CSS class to find navigation
11235 * menus.
11236 * @param {string} [options.attribInitTarget] The attribute name in the
11237 * launcher buttons to find target navigation menu.
11238 * @param {string} [options.selectorShellNavSubmenu] The CSS selector for a
11239 * nav submenu
11240 * @param {string} [options.selectorShellNavLink] The CSS selector for a nav
11241 * link
11242 * @param {string} [options.selectorShellNavLinkCurrent] The CSS selector for
11243 * the current nav link
11244 * @param {string} [options.selectorShellNavItem] The CSS selector for a nav
11245 * item
11246 * @param {string} [options.selectorShellNavCategory] The CSS selector for a
11247 * nav category
11248 * @param {string} [options.classShellNavItemActive] The CSS class for the
11249 * active nav item
11250 * @param {string} [options.classShellNavLinkCurrent] The CSS class for the
11251 * current lav link
11252 * @param {string} [options.classShellNavCategoryExpanded] The CSS class
11253 * for an expanded nav category
11254 */
11255 function NavigationMenu(element, options) {
11256 var _this;
11257
11258 _classCallCheck(this, NavigationMenu);
11259
11260 _this = _possibleConstructorReturn(this, _getPrototypeOf(NavigationMenu).call(this, element, options));
11261
11262 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentNavigation", function () {
11263 return _this.element.ownerDocument.activeElement;
11264 });
11265
11266 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "navigate", function (direction) {
11267 var items = _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorFocusableNavItems));
11268
11269 var start = _this.getCurrentNavigation();
11270
11271 var getNextItem = function getNextItem(old) {
11272 var handleUnderflow = function handleUnderflow(index, length) {
11273 return index + (index >= 0 ? 0 : length);
11274 };
11275
11276 var handleOverflow = function handleOverflow(index, length) {
11277 return index - (index < length ? 0 : length);
11278 }; // `items.indexOf(old)` may be -1 (Scenario of no previous focus)
11279
11280
11281 var index = Math.max(items.indexOf(old) + direction, -1);
11282 return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
11283 };
11284
11285 getNextItem(start).focus();
11286 });
11287
11288 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
11289 // handle Esc
11290 var isExpanded = !_this.element.hasAttribute('hidden');
11291
11292 if (event.which === 27 && isExpanded) {
11293 _this.changeState('collapsed');
11294
11295 if (_this.triggerButton) {
11296 _this.triggerButton.focus();
11297 }
11298
11299 return;
11300 } // handle up/down arrow keys
11301
11302
11303 var matchesNavSubmenu = eventMatches(event, _this.options.selectorShellNavSubmenu);
11304 var matchesShellNavLink = eventMatches(event, _this.options.selectorShellNavLink);
11305
11306 if (!matchesNavSubmenu && !matchesShellNavLink) {
11307 return;
11308 }
11309
11310 var navigationKeyCodes = {
11311 38: _this.constructor.NAVIGATE.BACKWARD,
11312 // up arrow
11313 40: _this.constructor.NAVIGATE.FORWARD // down arrow
11314
11315 };
11316 var navigationKeyCodeMatches = navigationKeyCodes[event.which];
11317
11318 if (navigationKeyCodeMatches) {
11319 event.preventDefault(); // prevent arrow keys from scrolling
11320
11321 _this.navigate(navigationKeyCodeMatches);
11322 }
11323 });
11324
11325 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusOut", function (event) {
11326 var nextTargetIsOfSelf = _this.element.contains(event.relatedTarget) || event.relatedTarget === _this.triggerButton || !event.relatedTarget;
11327
11328 var oldTargetIsOfSelf = _this.element.contains(event.target);
11329
11330 if (oldTargetIsOfSelf && !nextTargetIsOfSelf) {
11331 _this.changeState('collapsed');
11332
11333 _this.triggerButton.focus();
11334 }
11335 });
11336
11337 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "changeNavSubmenuState", function (_ref) {
11338 var matchesNavSubmenu = _ref.matchesNavSubmenu,
11339 shouldBeCollapsed = _ref.shouldBeCollapsed;
11340 var shellNavCategory = matchesNavSubmenu.closest(_this.options.selectorShellNavCategory);
11341
11342 if (!shellNavCategory) {
11343 return;
11344 }
11345
11346 matchesNavSubmenu.setAttribute('aria-expanded', !shouldBeCollapsed);
11347 shellNavCategory.classList.toggle(_this.options.classShellNavCategoryExpanded);
11348 Array.prototype.forEach.call(shellNavCategory.querySelectorAll(_this.options.selectorShellNavLink), function (item) {
11349 item.tabIndex = !shouldBeCollapsed ? 0 : -1;
11350 });
11351 });
11352
11353 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleClick", function (event) {
11354 var matchesNavSubmenu = eventMatches(event, _this.options.selectorShellNavSubmenu);
11355 var matchesShellNavLink = eventMatches(event, _this.options.selectorShellNavLink);
11356 var matchesNestedShellNavLink = eventMatches(event, _this.options.selectorShellNestedNavLink);
11357
11358 if (!matchesNavSubmenu && !matchesShellNavLink) {
11359 return;
11360 }
11361
11362 if (matchesNestedShellNavLink) {
11363 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorShellNavLinkCurrent)).forEach(function (el) {
11364 el.classList.remove(_this.options.classShellNavItemActive, _this.options.classShellNavLinkCurrent);
11365 });
11366
11367 matchesNestedShellNavLink.closest(_this.options.selectorShellNavNestedCategory).classList.add(_this.options.classShellNavItemActive);
11368 return;
11369 }
11370
11371 if (matchesNavSubmenu) {
11372 var isExpanded = matchesNavSubmenu.getAttribute('aria-expanded') === 'true';
11373
11374 _this.changeNavSubmenuState({
11375 matchesNavSubmenu: matchesNavSubmenu,
11376 isExpanded: isExpanded
11377 });
11378
11379 return;
11380 }
11381
11382 if (matchesShellNavLink) {
11383 _toConsumableArray(_this.element.querySelectorAll(_this.options.selectorShellNavLinkCurrent)).forEach(function (el) {
11384 el.classList.remove(_this.options.classShellNavItemActive, _this.options.classShellNavLinkCurrent);
11385 });
11386
11387 matchesShellNavLink.closest(_this.options.selectorShellNavItem).classList.add(_this.options.classShellNavItemActive);
11388 }
11389 });
11390
11391 _this.manage(on(element, 'click', _this._handleClick));
11392
11393 _this.manage(on(element, 'keydown', _this._handleKeyDown));
11394
11395 _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
11396 if (!_this.element.hasAttribute('hidden') && !_this.triggerButton.contains(event.target) && !_this.element.contains(event.target)) {
11397 _this.changeState('collapsed');
11398 }
11399 }));
11400
11401 var hasFocusOut = 'onfocusout' in window;
11402
11403 _this.manage(on(_this.element, hasFocusOut ? 'focusout' : 'blur', _this._handleFocusOut, !hasFocusOut));
11404
11405 return _this;
11406 }
11407 /**
11408 * @returns {Element} Currently highlighted element.
11409 */
11410
11411
11412 _createClass(NavigationMenu, null, [{
11413 key: "options",
11414
11415 /**
11416 * The component options.
11417 * If `options` is specified in the constructor,
11418 * {@linkcode NavigationMenu.create .create()}, or
11419 * {@linkcode NavigationMenu.init .init()},
11420 * properties in this object are overriden for the instance being create and
11421 * how {@linkcode NavigationMenu.init .init()} works.
11422 * @member NavigationMenu.options
11423 * @type {Object}
11424 * @property {string} selectorInit The CSS class to find navigation menus.
11425 * @property {string} attribInitTarget The attribute name in the
11426 * launcher buttons to find target navigation menu.
11427 * @property {string[]} initEventNames The events that the component
11428 * will handles
11429 */
11430 get: function get() {
11431 var prefix = settings_1.prefix;
11432 return Object.assign(Object.create(NavigationMenuPanel.options), {
11433 selectorInit: '[data-navigation-menu]',
11434 attribInitTarget: 'data-navigation-menu-target',
11435 selectorShellNavSubmenu: ".".concat(prefix, "--navigation__category-toggle"),
11436 selectorShellNavLink: ".".concat(prefix, "--navigation-link"),
11437 selectorShellNestedNavLink: ".".concat(prefix, "--navigation__category-item > a.").concat(prefix, "--navigation-link"),
11438 selectorShellNavLinkCurrent: ".".concat(prefix, "--navigation-item--active,.").concat(prefix, "--navigation__category-item--active"),
11439 selectorFocusableNavItems: "\n .".concat(prefix, "--navigation__category-toggle,\n .").concat(prefix, "--navigation-item > .").concat(prefix, "--navigation-link,\n .").concat(prefix, "--navigation-link[tabindex=\"0\"]\n "),
11440 selectorShellNavItem: ".".concat(prefix, "--navigation-item"),
11441 selectorShellNavCategory: ".".concat(prefix, "--navigation__category"),
11442 selectorShellNavNestedCategory: ".".concat(prefix, "--navigation__category-item"),
11443 classShellNavItemActive: "".concat(prefix, "--navigation-item--active"),
11444 classShellNavLinkCurrent: "".concat(prefix, "--navigation__category-item--active"),
11445 classShellNavCategoryExpanded: "".concat(prefix, "--navigation__category--expanded")
11446 });
11447 }
11448 /**
11449 * Enum for navigating backward/forward.
11450 * @readonly
11451 * @member NavigationMenuPanel.NAVIGATE
11452 * @type {Object}
11453 * @property {number} BACKWARD Navigating backward.
11454 * @property {number} FORWARD Navigating forward.
11455 */
11456
11457 }]);
11458
11459 return NavigationMenu;
11460 }(NavigationMenuPanel);
11461
11462 _defineProperty(NavigationMenu, "components",
11463 /* #__PURE_CLASS_PROPERTY__ */
11464 new WeakMap());
11465
11466 _defineProperty(NavigationMenu, "NAVIGATE",
11467 /* #__PURE_CLASS_PROPERTY__ */
11468 {
11469 BACKWARD: -1,
11470 FORWARD: 1
11471 });
11472
11473 /**
11474 * Differentiate between keyboard and mouse-triggered focusout/blur events
11475 * @param {Element} node The element to attach event listeners to
11476 * @param {string} name The event name to listen to
11477 * @param {Function} callback The callback function to invoke
11478 * @returns {Handle} The handle to release the attached event handler
11479 */
11480 function onFocusByKeyboard(node, name, callback) {
11481 var hasFocusout = 'onfocusout' in window;
11482 var focusinEventName = hasFocusout ? 'focusin' : 'focus';
11483 var focusoutEventName = hasFocusout ? 'focusout' : 'blur';
11484 /**
11485 * Event types supported by this function
11486 * @type {Object<string, string>}
11487 */
11488
11489 var supportedEvents = {
11490 focus: focusinEventName,
11491 blur: focusoutEventName
11492 };
11493 var eventName = supportedEvents[name];
11494
11495 if (!eventName) {
11496 throw new Error('Unsupported event!');
11497 }
11498
11499 var clicked;
11500
11501 var handleMousedown = function handleMousedown() {
11502 clicked = true;
11503 requestAnimationFrame(function () {
11504 clicked = false;
11505 });
11506 };
11507
11508 var handleFocusin = function handleFocusin(evt) {
11509 if (!clicked) {
11510 callback(evt);
11511 }
11512 };
11513
11514 node.ownerDocument.addEventListener('mousedown', handleMousedown);
11515 node.addEventListener(eventName, handleFocusin, !hasFocusout);
11516 return {
11517 release: function release() {
11518 if (handleFocusin) {
11519 node.removeEventListener(eventName, handleFocusin, !hasFocusout);
11520 handleFocusin = null;
11521 }
11522
11523 if (handleMousedown) {
11524 node.ownerDocument.removeEventListener('mousedown', handleMousedown);
11525 handleMousedown = null;
11526 }
11527
11528 return null;
11529 }
11530 };
11531 }
11532
11533 var ProductSwitcher =
11534 /*#__PURE__*/
11535 function (_NavigationMenuPanel) {
11536 _inherits(ProductSwitcher, _NavigationMenuPanel);
11537
11538 /**
11539 * A navigation menu
11540 * @extends NavigationMenuPanel
11541 * @param {HTMLElement} element The element working as a selector.
11542 * @param {Object} [options] The component options.
11543 * @param {string} [options.selectorInit] The CSS class to find product
11544 * switchers
11545 * @param {string} [options.attribInitTarget] The attribute name in the
11546 * launcher buttons to find target product switcher
11547 * @param {string} [options.classProductSwitcherExpanded] The CSS class
11548 * for an expanded product switcher
11549 */
11550 function ProductSwitcher(element, options) {
11551 var _this;
11552
11553 _classCallCheck(this, ProductSwitcher);
11554
11555 _this = _possibleConstructorReturn(this, _getPrototypeOf(ProductSwitcher).call(this, element, options));
11556
11557 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "current", '');
11558
11559 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "triggerButtonIds", new Set());
11560
11561 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleFocusOut", function (event) {
11562 if (_this.element.contains(event.relatedTarget)) {
11563 return;
11564 }
11565
11566 var currentTriggerButton = _this.element.ownerDocument.getElementById(_this.current);
11567
11568 if (currentTriggerButton && event.relatedTarget && !event.relatedTarget.matches(_this.options.selectorFloatingMenus)) {
11569 currentTriggerButton.focus();
11570 }
11571 });
11572
11573 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_handleKeyDown", function (event) {
11574 var isExpanded = !_this.element.hasAttribute('hidden');
11575
11576 if (event.which === 27 && isExpanded) {
11577 var triggerButton = _this.current;
11578
11579 _this.changeState(_this.constructor.SELECT_NONE);
11580
11581 _this.element.ownerDocument.getElementById(triggerButton).focus();
11582 }
11583 });
11584
11585 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "createdByLauncher", function (event) {
11586 var isExpanded = _this.element.classList.contains(_this.options.classProductSwitcherExpanded);
11587
11588 var launcher = event.delegateTarget;
11589
11590 if (!launcher.id) {
11591 launcher.id = "__carbon-product-switcher-launcher-".concat(Math.random().toString(36).substr(2));
11592 }
11593
11594 var current = launcher.id;
11595
11596 _this.changeState(isExpanded && _this.current === current ? _this.constructor.SELECT_NONE : current);
11597 });
11598
11599 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "shouldStateBeChanged", function (current) {
11600 return _this.current !== current;
11601 });
11602
11603 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_changeState", function (state, callback) {
11604 _this.element.classList.toggle(_this.options.classProductSwitcherExpanded, state !== _this.constructor.SELECT_NONE);
11605
11606 _this.current = state;
11607
11608 if (_this.current !== _this.constructor.SELECT_NONE) {
11609 _this.triggerButtonIds.add(_this.current);
11610 } // deactivate all other trigger buttons
11611
11612
11613 _this.triggerButtonIds.forEach(function (id) {
11614 var button = _this.element.ownerDocument.getElementById(id);
11615
11616 var label = button.getAttribute(_this.options.attribLabelExpand);
11617 button.classList.remove(_this.options.classNavigationMenuPanelHeaderActionActive);
11618 button.setAttribute('aria-label', label);
11619 button.setAttribute('title', label);
11620 }); // set active trigger button attributes
11621
11622
11623 var currentTriggerButton = _this.element.ownerDocument.getElementById(_this.current);
11624
11625 if (currentTriggerButton) {
11626 var label = currentTriggerButton.getAttribute(_this.options.attribLabelCollapse);
11627 currentTriggerButton.classList.toggle(_this.options.classNavigationMenuPanelHeaderActionActive);
11628 currentTriggerButton.setAttribute('aria-label', label);
11629 currentTriggerButton.setAttribute('title', label);
11630 }
11631
11632 if (state !== _this.constructor.SELECT_NONE) {
11633 _this.element.setAttribute('tabindex', '0');
11634
11635 _this.element.focus();
11636 } else {
11637 _this.element.setAttribute('tabindex', '-1');
11638 }
11639
11640 callback();
11641 });
11642
11643 _this.manage(on(element, 'keydown', _this._handleKeyDown));
11644
11645 _this.manage(onFocusByKeyboard(element, 'blur', _this._handleFocusOut));
11646
11647 return _this;
11648 }
11649 /**
11650 * id of currently active trigger button
11651 * @type {string}
11652 */
11653
11654
11655 _createClass(ProductSwitcher, [{
11656 key: "release",
11657 value: function release() {
11658 this.triggerButtonIds.clear();
11659 return _get(_getPrototypeOf(ProductSwitcher.prototype), "release", this).call(this);
11660 }
11661 /**
11662 * The map associating DOM element and ProductSwitcher instance.
11663 * @member ProductSwitcher.components
11664 * @type {WeakMap}
11665 */
11666
11667 }], [{
11668 key: "options",
11669
11670 /**
11671 * The component options.
11672 * If `options` is specified in the constructor,
11673 * {@linkcode ProductSwitcher.create .create()}, or
11674 * {@linkcode ProductSwitcher.init .init()},
11675 * properties in this object are overriden for the instance being create and
11676 * how {@linkcode ProductSwitcher.init .init()} works.
11677 * @member ProductSwitcher.options
11678 * @type {Object}
11679 * @property {string} selectorInit The CSS class to find popup navs.
11680 * @property {string} attribInitTarget The attribute name in the
11681 * launcher buttons to find target popup nav.
11682 * @property {string[]} initEventNames The events that the component
11683 * will handles
11684 */
11685 get: function get$$1() {
11686 var prefix = settings_1.prefix;
11687 return Object.assign(Object.create(NavigationMenuPanel.options), {
11688 selectorInit: '[data-product-switcher]',
11689 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 "),
11690 attribInitTarget: 'data-product-switcher-target',
11691 classProductSwitcherExpanded: "".concat(prefix, "--panel--expanded")
11692 });
11693 }
11694 }]);
11695
11696 return ProductSwitcher;
11697 }(NavigationMenuPanel);
11698
11699 _defineProperty(ProductSwitcher, "SELECT_NONE",
11700 /* #__PURE_CLASS_PROPERTY__ */
11701 '__carbon-product-switcher-launcher-NONE');
11702
11703 _defineProperty(ProductSwitcher, "components",
11704 /* #__PURE_CLASS_PROPERTY__ */
11705 new WeakMap());
11706
11707 var PaginationNav =
11708 /*#__PURE__*/
11709 function (_mixin) {
11710 _inherits(PaginationNav, _mixin);
11711
11712 /**
11713 * Pagination Nav component
11714 * @extends CreateComponent
11715 * @extends InitComponentBySearch
11716 * @extends Handles
11717 * @param {HTMLElement} element The element working as a pagination nav.
11718 */
11719 function PaginationNav(element, options) {
11720 var _this;
11721
11722 _classCallCheck(this, PaginationNav);
11723
11724 _this = _possibleConstructorReturn(this, _getPrototypeOf(PaginationNav).call(this, element, options));
11725
11726 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getActivePageNumber", function () {
11727 var pageNum;
11728
11729 var activePageElement = _this.element.querySelector(_this.options.selectorPageActive);
11730
11731 if (activePageElement) {
11732 pageNum = Number(activePageElement.getAttribute(_this.options.attribPage));
11733 }
11734
11735 return pageNum;
11736 });
11737
11738 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "clearActivePage", function (evt) {
11739 var pageButtonNodeList = _this.element.querySelectorAll(_this.options.selectorPageButton);
11740
11741 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
11742
11743 Array.prototype.forEach.call(pageButtonNodeList, function (el) {
11744 el.classList.remove(_this.options.classActive, _this.options.classDisabled);
11745 el.removeAttribute(_this.options.attribActive);
11746 el.removeAttribute('aria-disabled');
11747 el.removeAttribute('aria-current');
11748 });
11749
11750 if (pageSelectElement) {
11751 pageSelectElement.removeAttribute('aria-current');
11752 var pageSelectElementOptions = pageSelectElement.options;
11753 Array.prototype.forEach.call(pageSelectElementOptions, function (el) {
11754 el.removeAttribute(_this.options.attribActive);
11755 });
11756
11757 if (!evt.target.matches(_this.options.selectorPageSelect)) {
11758 pageSelectElement.classList.remove(_this.options.classActive);
11759 pageSelectElement.value = '';
11760 }
11761 }
11762 });
11763
11764 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleClick", function (evt) {
11765 if (!evt.target.getAttribute('aria-disabled') === true) {
11766 var nextActivePageNumber = _this.getActivePageNumber();
11767
11768 var pageElementNodeList = _this.element.querySelectorAll(_this.options.selectorPageElement);
11769
11770 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
11771
11772 _this.clearActivePage(evt);
11773
11774 if (evt.target.matches(_this.options.selectorPageButton)) {
11775 nextActivePageNumber = Number(evt.target.getAttribute(_this.options.attribPage));
11776 }
11777
11778 if (evt.target.matches(_this.options.selectorPagePrevious)) {
11779 nextActivePageNumber -= 1;
11780 }
11781
11782 if (evt.target.matches(_this.options.selectorPageNext)) {
11783 nextActivePageNumber += 1;
11784 }
11785
11786 var pageTargetElement = pageElementNodeList[nextActivePageNumber - 1];
11787 pageTargetElement.setAttribute(_this.options.attribActive, true);
11788
11789 if (pageTargetElement.tagName === 'OPTION') {
11790 pageSelectElement.value = _this.getActivePageNumber();
11791 pageSelectElement.classList.add(_this.options.classActive);
11792 pageSelectElement.setAttribute('aria-current', 'page');
11793 } else {
11794 pageTargetElement.classList.add(_this.options.classActive, _this.options.classDisabled);
11795 pageTargetElement.setAttribute('aria-disabled', true);
11796 pageTargetElement.setAttribute('aria-current', 'page');
11797 }
11798
11799 _this.setPrevNextStates();
11800 }
11801 });
11802
11803 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleSelectChange", function (evt) {
11804 _this.clearActivePage(evt);
11805
11806 var pageSelectElement = _this.element.querySelector(_this.options.selectorPageSelect);
11807
11808 var pageSelectElementOptions = pageSelectElement.options;
11809 pageSelectElementOptions[pageSelectElementOptions.selectedIndex].setAttribute(_this.options.attribActive, true);
11810 evt.target.setAttribute('aria-current', 'page');
11811 evt.target.classList.add(_this.options.classActive);
11812
11813 _this.setPrevNextStates();
11814 });
11815
11816 _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "setPrevNextStates", function () {
11817 var pageElementNodeList = _this.element.querySelectorAll(_this.options.selectorPageElement);
11818
11819 var totalPages = pageElementNodeList.length;
11820
11821 var pageDirectionElementPrevious = _this.element.querySelector(_this.options.selectorPagePrevious);
11822
11823 var pageDirectionElementNext = _this.element.querySelector(_this.options.selectorPageNext);
11824
11825 if (pageDirectionElementPrevious) {
11826 if (_this.getActivePageNumber() <= 1) {
11827 pageDirectionElementPrevious.setAttribute('aria-disabled', true);
11828 pageDirectionElementPrevious.classList.add(_this.options.classDisabled);
11829 } else {
11830 pageDirectionElementPrevious.removeAttribute('aria-disabled');
11831 pageDirectionElementPrevious.classList.remove(_this.options.classDisabled);
11832 }
11833 }
11834
11835 if (pageDirectionElementNext) {
11836 if (_this.getActivePageNumber() >= totalPages) {
11837 pageDirectionElementNext.setAttribute('aria-disabled', true);
11838 pageDirectionElementNext.classList.add(_this.options.classDisabled);
11839 } else {
11840 pageDirectionElementNext.removeAttribute('aria-disabled');
11841 pageDirectionElementNext.classList.remove(_this.options.classDisabled);
11842 }
11843 }
11844 });
11845
11846 _this.manage(on(_this.element, 'click', function (evt) {
11847 return _this.handleClick(evt);
11848 }));
11849
11850 _this.manage(on(_this.element, 'change', function (evt) {
11851 if (evt.target.matches(_this.options.selectorPageSelect)) {
11852 _this.handleSelectChange(evt);
11853 }
11854 }));
11855
11856 return _this;
11857 }
11858 /**
11859 * Get active page number
11860 */
11861
11862
11863 _createClass(PaginationNav, null, [{
11864 key: "options",
11865
11866 /**
11867 * The component options.
11868 * If `options` is specified in the constructor, {@linkcode PaginationNav.create .create()},
11869 * or {@linkcode PaginationNav.init .init()},
11870 * properties in this object are overriden for the instance being create and how {@linkcode PaginationNav.init .init()} works.
11871 * @member PaginationNav.options
11872 * @type {Object}
11873 * @property {string} selectorInit The data attribute to find pagination nav.
11874 * @property {string} selectorPageElement The data attribute to find page element.
11875 * @property {string} selectorPageButton The data attribute to find page interactive element.
11876 * @property {string} selectorPageDirection The data attribute to find page change element.
11877 * @property {string} selectorPageSelect The data attribute to find page select element.
11878 * @property {string} selectorPageActive The data attribute to find active page element.
11879 * @property {string} [classActive] The CSS class for page's selected state.
11880 * @property {string} [classDisabled] The CSS class for page's disabled state.
11881 */
11882 get: function get() {
11883 var prefix = settings_1.prefix;
11884 return {
11885 selectorInit: '[data-pagination-nav]',
11886 selectorPageElement: '[data-page]',
11887 selectorPageButton: '[data-page-button]',
11888 selectorPagePrevious: '[data-page-previous]',
11889 selectorPageNext: '[data-page-next]',
11890 selectorPageSelect: '[data-page-select]',
11891 selectorPageActive: '[data-page-active="true"]',
11892 attribPage: 'data-page',
11893 attribActive: 'data-page-active',
11894 classActive: "".concat(prefix, "--pagination-nav__page--active"),
11895 classDisabled: "".concat(prefix, "--pagination-nav__page--disabled")
11896 };
11897 }
11898 }]);
11899
11900 return PaginationNav;
11901 }(mixin(createComponent, initComponentBySearch, handles));
11902
11903 _defineProperty(PaginationNav, "components",
11904 /* #__PURE_CLASS_PROPERTY__ */
11905 new WeakMap());
11906
11907 /**
11908 * Copyright IBM Corp. 2016, 2018
11909 *
11910 * This source code is licensed under the Apache-2.0 license found in the
11911 * LICENSE file in the root directory of this source tree.
11912 */
11913
11914 var components = /*#__PURE__*/Object.freeze({
11915 Checkbox: Checkbox,
11916 FileUploader: FileUploader,
11917 FabButton: fab,
11918 ContentSwitcher: ContentSwitcher,
11919 Tab: Tab,
11920 OverflowMenu: OverflowMenu,
11921 Modal: Modal,
11922 Loading: Loading,
11923 InlineLoading: InlineLoading,
11924 Dropdown: Dropdown,
11925 NumberInput: NumberInput,
11926 DataTable: dataTable,
11927 DataTableV2: DataTableV2,
11928 DatePicker: DatePicker,
11929 LeftNav: leftNav,
11930 ProfileSwitcher: profileSwitcher,
11931 Pagination: Pagination,
11932 Search: Search,
11933 Accordion: Accordion,
11934 CopyButton: CopyButton,
11935 Notification: Notification,
11936 Toolbar: Toolbar,
11937 Tooltip: Tooltip,
11938 ProgressIndicator: ProgressIndicator,
11939 FloatingMenu: FloatingMenu,
11940 StructuredList: StructuredList,
11941 Slider: Slider,
11942 Tile: Tile,
11943 Carousel: carousel,
11944 Lightbox: lightbox,
11945 CodeSnippet: CodeSnippet,
11946 TextInput: TextInput,
11947 SideNav: SideNav,
11948 HeaderSubmenu: HeaderSubmenu,
11949 HeaderNav: HeaderNav,
11950 NavigationMenu: NavigationMenu,
11951 ProductSwitcher: ProductSwitcher,
11952 PaginationNav: PaginationNav
11953 });
11954
11955 /**
11956 * Copyright IBM Corp. 2016, 2018
11957 *
11958 * This source code is licensed under the Apache-2.0 license found in the
11959 * LICENSE file in the root directory of this source tree.
11960 */
11961 var components$1 = components;
11962 /**
11963 * Instantiates components automatically
11964 * by searching for elements with `data-component-name` (e.g. `data-loading`) attribute
11965 * or upon DOM events (e.g. clicking) on such elements.
11966 * See each components' static `.init()` methods for details.
11967 * @private
11968 */
11969
11970 var init = function init() {
11971 var componentClasses = Object.keys(components$1).map(function (key) {
11972 return components$1[key];
11973 }).filter(function (component) {
11974 return typeof component.init === 'function';
11975 });
11976
11977 if (!settings_1.disableAutoInit) {
11978 componentClasses.forEach(function (Clz) {
11979 var h = Clz.init();
11980 });
11981 }
11982 };
11983
11984 if (document.readyState === 'loading') {
11985 document.addEventListener('DOMContentLoaded', init);
11986 } else {
11987 // DOMContentLoaded has been fired already
11988 // Let consumer have chance to see if it wants automatic instantiation disabled, and then run automatic instantiation otherwise
11989 setTimeout(init, 0);
11990 }
11991
11992 /**
11993 * Copyright IBM Corp. 2016, 2018
11994 *
11995 * This source code is licensed under the Apache-2.0 license found in the
11996 * LICENSE file in the root directory of this source tree.
11997 */
11998
11999 /**
12000 * Copyright IBM Corp. 2016, 2018
12001 *
12002 * This source code is licensed under the Apache-2.0 license found in the
12003 * LICENSE file in the root directory of this source tree.
12004 */
12005 var forEach$1 = Array.prototype.forEach;
12006
12007 var createAndReleaseComponentsUponDOMMutation = function createAndReleaseComponentsUponDOMMutation(records, componentClasses, componentClassesForWatchInit, options) {
12008 records.forEach(function (record) {
12009 forEach$1.call(record.addedNodes, function (node) {
12010 if (node.nodeType === Node.ELEMENT_NODE) {
12011 componentClassesForWatchInit.forEach(function (Clz) {
12012 Clz.init(node, options);
12013 });
12014 }
12015 });
12016 forEach$1.call(record.removedNodes, function (node) {
12017 if (node.nodeType === Node.ELEMENT_NODE) {
12018 componentClasses.forEach(function (Clz) {
12019 if (node.matches(Clz.options.selectorInit)) {
12020 var instance = Clz.components.get(node);
12021
12022 if (instance) {
12023 instance.release();
12024 }
12025 } else {
12026 forEach$1.call(node.querySelectorAll(Clz.options.selectorInit), function (element) {
12027 var instance = Clz.components.get(element);
12028
12029 if (instance) {
12030 instance.release();
12031 }
12032 });
12033 }
12034 });
12035 }
12036 });
12037 });
12038 };
12039 /**
12040 * Automatically instantiates/destroys components in the given element, by watching for DOM additions/removals.
12041 * @param {Node} target The DOM node to instantiate components in. Should be a document or an element.
12042 * @param {Object} [options] The component options.
12043 * @returns {Handle} The handle to stop watching.
12044 */
12045
12046
12047 function watch () {
12048 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
12049 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
12050
12051 if (target.nodeType !== Node.ELEMENT_NODE && target.nodeType !== Node.DOCUMENT_NODE) {
12052 throw new TypeError('DOM document or DOM element should be given to watch for DOM node to create/release components.');
12053 }
12054
12055 var componentClasses = Object.keys(components).map(function (key) {
12056 return components[key];
12057 }).filter(function (component) {
12058 return typeof component.init === 'function';
12059 });
12060 var handles = componentClasses.map(function (Clz) {
12061 return Clz.init(target, options);
12062 }).filter(Boolean);
12063 var componentClassesForWatchInit = componentClasses.filter(function (Clz) {
12064 return !Clz.forLazyInit;
12065 });
12066 var observer = new MutationObserver(function (records) {
12067 createAndReleaseComponentsUponDOMMutation(records, componentClasses, componentClassesForWatchInit, options);
12068 });
12069 observer.observe(target, {
12070 childList: true,
12071 subtree: true
12072 });
12073 return {
12074 release: function release() {
12075 for (var handle = handles.pop(); handle; handle = handles.pop()) {
12076 handle.release();
12077 }
12078
12079 if (observer) {
12080 observer.disconnect();
12081 observer = null;
12082 }
12083 }
12084 };
12085 }
12086
12087 /**
12088 * Copyright IBM Corp. 2016, 2018
12089 *
12090 * This source code is licensed under the Apache-2.0 license found in the
12091 * LICENSE file in the root directory of this source tree.
12092 */
12093
12094 exports.watch = watch;
12095 exports.settings = settings_1;
12096 exports.Checkbox = Checkbox;
12097 exports.FileUploader = FileUploader;
12098 exports.FabButton = fab;
12099 exports.ContentSwitcher = ContentSwitcher;
12100 exports.Tab = Tab;
12101 exports.OverflowMenu = OverflowMenu;
12102 exports.Modal = Modal;
12103 exports.Loading = Loading;
12104 exports.InlineLoading = InlineLoading;
12105 exports.Dropdown = Dropdown;
12106 exports.NumberInput = NumberInput;
12107 exports.DataTable = dataTable;
12108 exports.DataTableV2 = DataTableV2;
12109 exports.DatePicker = DatePicker;
12110 exports.LeftNav = leftNav;
12111 exports.ProfileSwitcher = profileSwitcher;
12112 exports.Pagination = Pagination;
12113 exports.Search = Search;
12114 exports.Accordion = Accordion;
12115 exports.CopyButton = CopyButton;
12116 exports.Notification = Notification;
12117 exports.Toolbar = Toolbar;
12118 exports.Tooltip = Tooltip;
12119 exports.ProgressIndicator = ProgressIndicator;
12120 exports.FloatingMenu = FloatingMenu;
12121 exports.StructuredList = StructuredList;
12122 exports.Slider = Slider;
12123 exports.Tile = Tile;
12124 exports.Carousel = carousel;
12125 exports.Lightbox = lightbox;
12126 exports.CodeSnippet = CodeSnippet;
12127 exports.TextInput = TextInput;
12128 exports.SideNav = SideNav;
12129 exports.HeaderSubmenu = HeaderSubmenu;
12130 exports.HeaderNav = HeaderNav;
12131 exports.NavigationMenu = NavigationMenu;
12132 exports.ProductSwitcher = ProductSwitcher;
12133 exports.PaginationNav = PaginationNav;
12134
12135 return exports;
12136
12137}({}));