@schukai/monster 3.80.4 → 3.80.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,61 +12,61 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import {instanceSymbol} from "../../constants.mjs";
16
- import {internalSymbol} from "../../constants.mjs";
17
- import {buildMap} from "../../data/buildmap.mjs";
18
- import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
19
- import {positionPopper} from "./util/floating-ui.mjs";
15
+ import { instanceSymbol } from "../../constants.mjs";
16
+ import { internalSymbol } from "../../constants.mjs";
17
+ import { buildMap } from "../../data/buildmap.mjs";
18
+ import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
19
+ import { positionPopper } from "./util/floating-ui.mjs";
20
20
  import {
21
- addAttributeToken,
22
- findClosestByAttribute,
23
- removeAttributeToken,
21
+ addAttributeToken,
22
+ findClosestByAttribute,
23
+ removeAttributeToken,
24
24
  } from "../../dom/attributes.mjs";
25
25
  import {
26
- ATTRIBUTE_ERRORMESSAGE,
27
- ATTRIBUTE_PREFIX,
28
- ATTRIBUTE_ROLE,
26
+ ATTRIBUTE_ERRORMESSAGE,
27
+ ATTRIBUTE_PREFIX,
28
+ ATTRIBUTE_ROLE,
29
29
  } from "../../dom/constants.mjs";
30
- import {CustomControl} from "../../dom/customcontrol.mjs";
30
+ import { CustomControl } from "../../dom/customcontrol.mjs";
31
31
  import {
32
- assembleMethodSymbol,
33
- getSlottedElements,
34
- registerCustomElement,
32
+ assembleMethodSymbol,
33
+ getSlottedElements,
34
+ registerCustomElement,
35
35
  } from "../../dom/customelement.mjs";
36
36
  import {
37
- findTargetElementFromEvent,
38
- fireCustomEvent,
39
- fireEvent,
37
+ findTargetElementFromEvent,
38
+ fireCustomEvent,
39
+ fireEvent,
40
40
  } from "../../dom/events.mjs";
41
- import {getDocument} from "../../dom/util.mjs";
42
- import {Formatter} from "../../text/formatter.mjs";
43
- import {getGlobal} from "../../types/global.mjs";
44
- import {ID} from "../../types/id.mjs";
41
+ import { getDocument } from "../../dom/util.mjs";
42
+ import { Formatter } from "../../text/formatter.mjs";
43
+ import { getGlobal } from "../../types/global.mjs";
44
+ import { ID } from "../../types/id.mjs";
45
45
  import {
46
- isArray,
47
- isFunction,
48
- isInteger,
49
- isIterable,
50
- isObject,
51
- isPrimitive,
52
- isString,
46
+ isArray,
47
+ isFunction,
48
+ isInteger,
49
+ isIterable,
50
+ isObject,
51
+ isPrimitive,
52
+ isString,
53
53
  } from "../../types/is.mjs";
54
- import {Observer} from "../../types/observer.mjs";
55
- import {ProxyObserver} from "../../types/proxyobserver.mjs";
56
- import {validateArray, validateString} from "../../types/validate.mjs";
57
- import {Processing} from "../../util/processing.mjs";
58
- import {STYLE_DISPLAY_MODE_BLOCK} from "./constants.mjs";
59
- import {SelectStyleSheet} from "./stylesheet/select.mjs";
54
+ import { Observer } from "../../types/observer.mjs";
55
+ import { ProxyObserver } from "../../types/proxyobserver.mjs";
56
+ import { validateArray, validateString } from "../../types/validate.mjs";
57
+ import { Processing } from "../../util/processing.mjs";
58
+ import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
59
+ import { SelectStyleSheet } from "./stylesheet/select.mjs";
60
60
  import {
61
- getDocumentTranslations,
62
- Translations,
61
+ getDocumentTranslations,
62
+ Translations,
63
63
  } from "../../i18n/translations.mjs";
64
64
 
65
65
  export {
66
- Select,
67
- popperElementSymbol,
68
- getSummaryTemplate,
69
- getSelectionTemplate,
66
+ Select,
67
+ popperElementSymbol,
68
+ getSummaryTemplate,
69
+ getSelectionTemplate,
70
70
  };
71
71
 
72
72
  /**
@@ -199,7 +199,7 @@ const popperFilterElementSymbol = Symbol("popperFilterElement");
199
199
  * @type {Symbol}
200
200
  */
201
201
  const popperFilterContainerElementSymbol = Symbol(
202
- "popperFilterContainerElement",
202
+ "popperFilterContainerElement",
203
203
  );
204
204
 
205
205
  /**
@@ -282,6 +282,7 @@ const FILTER_POSITION_INLINE = "inline";
282
282
  *
283
283
  * @example /examples/components/form/select-with-options Select with options
284
284
  * @example /examples/components/form/select-multiple Multiple selection
285
+ * @example /examples/components/form/select-filter Filter
285
286
  * @example /examples/components/form/select-fetch Fetch options
286
287
  * @example /examples/components/form/select-lazy Lazy load
287
288
  * @example /examples/components/form/select-remote-filter Remote filter
@@ -292,599 +293,611 @@ const FILTER_POSITION_INLINE = "inline";
292
293
  * @fires monster-changed
293
294
  */
294
295
  class Select extends CustomControl {
295
- /**
296
- *
297
- */
298
- constructor() {
299
- super();
300
- initOptionObserver.call(this);
301
- }
302
-
303
- /**
304
- * This method is called by the `instanceof` operator.
305
- * @return {Symbol}
306
- */
307
- static get [instanceSymbol]() {
308
- return Symbol.for("@schukai/monster/components/form/select@@instance");
309
- }
310
-
311
- /**
312
- * The current selection of the Select
313
- *
314
- * ```
315
- * e = document.querySelector('monster-select');
316
- * console.log(e.value)
317
- * // ↦ 1
318
- * // ↦ ['1','2']
319
- * ```
320
- *
321
- * @return {string}
322
- */
323
- get value() {
324
- return convertSelectionToValue.call(this, this.getOption("selection"));
325
- }
326
-
327
- /**
328
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
329
- * @return {boolean}
330
- */
331
- static get formAssociated() {
332
- return true;
333
- }
334
-
335
- /**
336
- * Set selection
337
- *
338
- * ```
339
- * e = document.querySelector('monster-select');
340
- * e.value=1
341
- * ```
342
- *
343
- * @property {string|array} value
344
- * @throws {Error} unsupported type
345
- * @fires monster-selected this event is fired when the selection is set
346
- */
347
- set value(value) {
348
- const result = convertValueToSelection.call(this, value);
349
- setSelection
350
- .call(this, result.selection)
351
- .then(() => {
352
- })
353
- .catch((e) => {
354
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
355
- });
356
- }
357
-
358
- /**
359
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
360
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
361
- *
362
- * The individual configuration values can be found in the table.
363
- *
364
- * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
365
- * @property {boolean} delegatesFocus=false lorem [see mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus)
366
- * @property {Object[]} options Selection of key identifier pairs available for selection and displayed in the dropdown.
367
- * @property {string} options[].label
368
- * @property {string} options[].value
369
- * @property {string} options[].visibility hidden or visible
370
- * @property {Array} selection Selected options
371
- * @property {Integer} showMaxOptions=10 Maximum number of visible options before a scroll bar should be displayed.
372
- * @property {string} type=radio Multiple (checkbox) or single selection (radio)
373
- * @property {string} name=(random id) Name of the form field
374
- * @property {string} url Load options from server per url
375
- * @property {object} lookup Load options from server per url
376
- * @property {string} lookup.url=null Load options from server per url
377
- * @property {boolean} lookup.grouping=false Load all selected options from server per url at once (true) or one by one (false)
378
- * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
379
- * @property {String} fetch.redirect=error
380
- * @property {String} fetch.method=GET
381
- * @property {String} fetch.mode=same-origin
382
- * @property {String} fetch.credentials=same-origin
383
- * @property {Object} fetch.headers={"accept":"application/json"}}
384
- * @property {Object} labels
385
- * @property {string} labels.cannot-be-loaded cannot be loaded
386
- * @property {string} labels.no-options-available no options available
387
- * @property {string} labels.select-an-option select an option
388
- * @property {string} labels.no-option no option in the list, maybe you have to change the filter
389
- * @property {Object} features List with features
390
- * @property {Boolean} features.clearAll=true Display of a delete button to delete the entire selection
391
- * @property {Boolean} features.clear=true Display of a delete key for deleting the specific selection
392
- * @property {Boolean} features.lazyLoad=false Load options when first opening the dropdown. (Hint; lazylLoad is not supported with remote filter)
393
- * @property {Boolean} features.closeOnSelect=false Close the dropdown when an option is selected (since 3.54.0)
394
- * @property {Boolean} features.emptyValueIfNoOptions=false If no options are available, the selection is set to an empty array
395
- * @property {Boolean} features.storeFetchedData=false Store fetched data in the object
396
- * @property {Boolean} features.useStrictValueComparison=true Use strict value comparison for the selection
397
- * @property {string} filter.defaultValue=null Default filter value, if the filter is empty, if the default value is null, then no request is made
398
- * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled (Hint; lazylLoad is not supported with remote filter, if you use remote filter, the lazyLoad is disabled)
399
- * @property {Object} templates Template definitions
400
- * @property {string} templates.main Main template
401
- * @property {string} templateMapping Mapping of the template placeholders
402
- * @property {string} templateMapping.selected Selected Template
403
- * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
404
- * @property {string} popper.placement=bottom PopperJS placement
405
- * @property {Object[]} modifiers={name:offset} PopperJS placement
406
- * @property {Object} mapping
407
- * @property {String} mapping.selector=* Path to select the appropriate entries
408
- * @property {String} mapping.labelTemplate="" template with the label placeholders in the form ${name}, where name is the key (**)
409
- * @property {String} mapping.valueTemplate="" template with the value placeholders in the form ${name}, where name is the key
410
- * @property {Monster.Components.Form~exampleFilterCallback|undefined} mapping.filter Filtering of values via a function
411
- * @property {Object} formatter
412
- * @property {Monster.Components.Form~formatterSelectionCallback|undefined} formatter.selection format selection label
413
- */
414
- get defaults() {
415
- return Object.assign(
416
- {},
417
- super.defaults,
418
- {
419
- toggleEventType: ["click", "touch"],
420
- delegatesFocus: false,
421
- options: [],
422
- selection: [],
423
- showMaxOptions: 10,
424
- type: "radio",
425
- name: new ID("s").toString(),
426
- features: {
427
- clearAll: true,
428
- clear: true,
429
- lazyLoad: false,
430
- closeOnSelect: false,
431
- emptyValueIfNoOptions: false,
432
- storeFetchedData: false,
433
- useStrictValueComparison: false,
434
- },
435
- url: null,
436
- lookup: {
437
- url: null,
438
- grouping: false,
439
- },
440
- labels: {
441
- "cannot-be-loaded": "Cannot be loaded",
442
- "no-options-available": noOptionsAvailableMessage,
443
- "click-to-load-options": clickToLoadOptionsMessage,
444
- "select-an-option": "Select an option",
445
- "summary-text": {
446
- zero: "No entries were selected",
447
- one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
448
- other:
449
- '<span class="monster-badge-primary-pill">${count}</span> entries were selected',
450
- },
451
- "no-options":
452
- "Unfortunately, there are no options available in the list.",
453
- "no-options-found":
454
- "No options are available in the list. Please consider modifying the filter.",
455
- },
456
- messages: {
457
- control: null,
458
- selected: null,
459
- emptyOptions: null,
460
- },
461
- fetch: {
462
- redirect: "error",
463
- method: "GET",
464
- mode: "same-origin",
465
- credentials: "same-origin",
466
- headers: {
467
- accept: "application/json",
468
- },
469
- },
470
- filter: {
471
- defaultValue: null,
472
- mode: FILTER_MODE_DISABLED,
473
- position: FILTER_POSITION_INLINE,
474
- marker: {
475
- open: "{",
476
- close: "}",
477
- },
478
- },
479
- classes: {
480
- badge: "monster-badge-primary",
481
- statusOrRemoveBadge: "empty",
482
- },
483
- mapping: {
484
- selector: "*",
485
- labelTemplate: "",
486
- valueTemplate: "",
487
- filter: null,
488
- },
489
- formatter: {
490
- selection: buildSelectionLabel,
491
- },
492
- templates: {
493
- main: getTemplate(),
494
- },
495
- templateMapping: {
496
- /** with the attribute `data-monster-selected-template` the template for the selected options can be defined. */
497
- selected: getSelectionTemplate(),
498
- },
499
-
500
- popper: {
501
- placement: "bottom",
502
- middleware: ["flip", "offset:1"],
503
- },
504
- },
505
- initOptionsFromArguments.call(this),
506
- );
507
- }
508
-
509
- /**
510
- * @return {Select}
511
- */
512
- [assembleMethodSymbol]() {
513
- const self = this;
514
- super[assembleMethodSymbol]();
515
-
516
- initControlReferences.call(self);
517
- initEventHandler.call(self);
518
-
519
- let lazyLoadFlag = self.getOption("features.lazyLoad", false);
520
- let remoteFilterFlag = self.getOption("filter.mode") === FILTER_MODE_REMOTE
521
-
522
- if (self.getOption("filter.mode") === FILTER_MODE_REMOTE) {
523
- self.getOption("features.lazyLoad", false);
524
- if (lazyLoadFlag === true) {
525
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "lazyLoad is not supported with remote filter");
526
- lazyLoadFlag = false;
527
- }
528
- }
529
-
530
- if (self.hasAttribute("value")) {
531
- new Processing(10, () => {
532
- this.value = this.getAttribute("value");
533
- })
534
- .run()
535
- .catch((e) => {
536
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
537
- });
538
- }
539
-
540
- if (self.getOption("url") !== null) {
541
- if (lazyLoadFlag || remoteFilterFlag) {
542
- lookupSelection.call(self);
543
- } else {
544
- self.fetch().catch((e) => {
545
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
546
- });
547
- }
548
- }
549
-
550
- let lastValue = self.value;
551
- self[internalSymbol].attachObserver(
552
- new Observer(function () {
553
- if (isObject(this) && this instanceof ProxyObserver) {
554
- const n = this.getSubject()?.options?.value;
555
-
556
- if (lastValue !== n) {
557
- lastValue = n;
558
- setSelection
559
- .call(self, n)
560
- .then(() => {
561
- })
562
- .catch((e) => {
563
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
564
- });
565
- }
566
- }
567
- }),
568
- );
569
-
570
- areOptionsAvailableAndInit.call(self);
571
-
572
- return this;
573
- }
574
-
575
- /**
576
- *
577
- * @return {*}
578
- * @throws {Error} storeFetchedData is not enabled
579
- * @since 3.66.0
580
- */
581
- getLastFetchedData() {
582
- if (this.getOption("features.storeFetchedData") === false) {
583
- throw new Error("storeFetchedData is not enabled");
584
- }
585
-
586
- return this?.[lastFetchedDataSymbol];
587
- }
588
-
589
- /**
590
- * The Button.click() method simulates a click on the internal button element.
591
- *
592
- * @since 3.27.0
593
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
594
- */
595
- click() {
596
- if (this.getOption("disabled") === true) {
597
- return;
598
- }
599
-
600
- toggle.call(this);
601
- }
602
-
603
- /**
604
- * The Button.focus() method sets focus on the internal button element.
605
- *
606
- * @since 3.27.0
607
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
608
- */
609
- focus(options) {
610
- if (this.getOption("disabled") === true) {
611
- return;
612
- }
613
-
614
- new Processing(() => {
615
- gatherState.call(this);
616
- focusFilter.call(this, options);
617
- })
618
- .run()
619
- .catch((e) => {
620
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
621
- });
622
- }
623
-
624
- /**
625
- * The Button.blur() method removes focus from the internal button element.
626
- * @link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur
627
- */
628
- blur() {
629
- new Processing(() => {
630
- gatherState.call(this);
631
- blurFilter.call(this);
632
- })
633
- .run()
634
- .catch((e) => {
635
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
636
- });
637
- }
638
-
639
- /**
640
- * If no url is specified, the options are taken from the Component itself.
641
- *
642
- * @param {string|URL} url URL to fetch the options
643
- * @return {Promise}
644
- */
645
- fetch(url) {
646
- return fetchIt.call(this, url);
647
- }
648
-
649
- /**
650
- * @return {void}
651
- */
652
- connectedCallback() {
653
- super.connectedCallback();
654
- const document = getDocument();
655
-
656
- for (const [, type] of Object.entries(["click", "touch"])) {
657
- // close on outside ui-events
658
- document.addEventListener(type, this[closeEventHandler]);
659
- }
660
-
661
- parseSlotsToOptions.call(this);
662
- attachResizeObserver.call(this);
663
- updatePopper.call(this);
664
-
665
- new Processing(() => {
666
- gatherState.call(this);
667
- focusFilter.call(this);
668
- }).run().catch((e) => {
669
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
670
- });
671
- }
672
-
673
- /**
674
- * @return {void}
675
- */
676
- disconnectedCallback() {
677
- super.disconnectedCallback();
678
- const document = getDocument();
679
-
680
- // close on outside ui-events
681
- for (const [, type] of Object.entries(["click", "touch"])) {
682
- document.removeEventListener(type, this[closeEventHandler]);
683
- }
684
-
685
- disconnectResizeObserver.call(this);
686
- }
687
-
688
- /**
689
- * Import Select Options from dataset
690
- * Not to be confused with the control defaults/options
691
- *
692
- * @param {array|object|Map|Set} data
693
- * @return {Select}
694
- * @throws {Error} map is not iterable
695
- * @throws {Error} missing label configuration
696
- * @fires monster-options-set this event is fired when the options are set
697
- */
698
- importOptions(data) {
699
- const mappingOptions = this.getOption("mapping", {});
700
- const selector = mappingOptions?.["selector"];
701
- const labelTemplate = mappingOptions?.["labelTemplate"];
702
- const valueTemplate = mappingOptions?.["valueTemplate"];
703
- const filter = mappingOptions?.["filter"];
704
-
705
- let flag = false;
706
- if (labelTemplate === "") {
707
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty label template");
708
- flag = true;
709
- }
710
-
711
- if (valueTemplate === "") {
712
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty value template");
713
- flag = true;
714
- }
715
-
716
- if (flag === true) {
717
- throw new Error("missing label configuration");
718
- }
719
-
720
- const map = buildMap(data, selector, labelTemplate, valueTemplate, filter);
721
-
722
- const options = []
723
-
724
- if (!isIterable(map)) {
725
- throw new Error("map is not iterable");
726
- }
727
-
728
- const visibility = "visible";
729
-
730
- map.forEach((label, value) => {
731
- options.push({
732
- value,
733
- label,
734
- visibility,
735
- data: map.get(value),
736
- });
737
- });
738
-
739
- runAsOptionLengthChanged.call(this, map.size);
740
- this.setOption("options", options);
741
-
742
- fireCustomEvent(this, "monster-options-set", {
743
- options,
744
- });
745
-
746
- return this;
747
- }
748
-
749
- /**
750
- * @private
751
- * @return {Select}
752
- */
753
- calcAndSetOptionsDimension() {
754
- calcAndSetOptionsDimension.call(this);
755
- return this;
756
- }
757
-
758
- /**
759
- *
760
- * @return {string}
761
- */
762
- static getTag() {
763
- return "monster-select";
764
- }
765
-
766
- /**
767
- *
768
- * @return {CSSStyleSheet[]}
769
- */
770
- static getCSSStyleSheet() {
771
- return [SelectStyleSheet];
772
- }
296
+ /**
297
+ *
298
+ */
299
+ constructor() {
300
+ super();
301
+ initOptionObserver.call(this);
302
+ }
303
+
304
+ /**
305
+ * This method is called by the `instanceof` operator.
306
+ * @return {Symbol}
307
+ */
308
+ static get [instanceSymbol]() {
309
+ return Symbol.for("@schukai/monster/components/form/select@@instance");
310
+ }
311
+
312
+ /**
313
+ * The current selection of the Select
314
+ *
315
+ * ```
316
+ * e = document.querySelector('monster-select');
317
+ * console.log(e.value)
318
+ * // ↦ 1
319
+ * // ↦ ['1','2']
320
+ * ```
321
+ *
322
+ * @return {string}
323
+ */
324
+ get value() {
325
+ return convertSelectionToValue.call(this, this.getOption("selection"));
326
+ }
327
+
328
+ /**
329
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
330
+ * @return {boolean}
331
+ */
332
+ static get formAssociated() {
333
+ return true;
334
+ }
335
+
336
+ /**
337
+ * Set selection
338
+ *
339
+ * ```
340
+ * e = document.querySelector('monster-select');
341
+ * e.value=1
342
+ * ```
343
+ *
344
+ * @property {string|array} value
345
+ * @throws {Error} unsupported type
346
+ * @fires monster-selected this event is fired when the selection is set
347
+ */
348
+ set value(value) {
349
+ const result = convertValueToSelection.call(this, value);
350
+ setSelection
351
+ .call(this, result.selection)
352
+ .then(() => {})
353
+ .catch((e) => {
354
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
355
+ });
356
+ }
357
+
358
+ /**
359
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
360
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
361
+ *
362
+ * The individual configuration values can be found in the table.
363
+ *
364
+ * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
365
+ * @property {boolean} delegatesFocus=false lorem [see mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus)
366
+ * @property {Object[]} options Selection of key identifier pairs available for selection and displayed in the dropdown.
367
+ * @property {string} options[].label
368
+ * @property {string} options[].value
369
+ * @property {string} options[].visibility hidden or visible
370
+ * @property {Array} selection Selected options
371
+ * @property {Integer} showMaxOptions=10 Maximum number of visible options before a scroll bar should be displayed.
372
+ * @property {string} type=radio Multiple (checkbox) or single selection (radio)
373
+ * @property {string} name=(random id) Name of the form field
374
+ * @property {string} url Load options from server per url
375
+ * @property {object} lookup Load options from server per url
376
+ * @property {string} lookup.url=null Load options from server per url
377
+ * @property {boolean} lookup.grouping=false Load all selected options from server per url at once (true) or one by one (false)
378
+ * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
379
+ * @property {String} fetch.redirect=error
380
+ * @property {String} fetch.method=GET
381
+ * @property {String} fetch.mode=same-origin
382
+ * @property {String} fetch.credentials=same-origin
383
+ * @property {Object} fetch.headers={"accept":"application/json"}}
384
+ * @property {Object} labels
385
+ * @property {string} labels.cannot-be-loaded cannot be loaded
386
+ * @property {string} labels.no-options-available no options available
387
+ * @property {string} labels.select-an-option select an option
388
+ * @property {string} labels.no-option no option in the list, maybe you have to change the filter
389
+ * @property {Object} features List with features
390
+ * @property {Boolean} features.clearAll=true Display of a delete button to delete the entire selection
391
+ * @property {Boolean} features.clear=true Display of a delete key for deleting the specific selection
392
+ * @property {Boolean} features.lazyLoad=false Load options when first opening the dropdown. (Hint; lazylLoad is not supported with remote filter)
393
+ * @property {Boolean} features.closeOnSelect=false Close the dropdown when an option is selected (since 3.54.0)
394
+ * @property {Boolean} features.emptyValueIfNoOptions=false If no options are available, the selection is set to an empty array
395
+ * @property {Boolean} features.storeFetchedData=false Store fetched data in the object
396
+ * @property {Boolean} features.useStrictValueComparison=true Use strict value comparison for the selection
397
+ * @property {string} filter.defaultValue=null Default filter value, if the filter is empty, if the default value is null, then no request is made
398
+ * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled (Hint; lazylLoad is not supported with remote filter, if you use remote filter, the lazyLoad is disabled)
399
+ * @property {Object} templates Template definitions
400
+ * @property {string} templates.main Main template
401
+ * @property {string} templateMapping Mapping of the template placeholders
402
+ * @property {string} templateMapping.selected Selected Template
403
+ * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
404
+ * @property {string} popper.placement=bottom PopperJS placement
405
+ * @property {Object[]} modifiers={name:offset} PopperJS placement
406
+ * @property {Object} mapping
407
+ * @property {String} mapping.selector=* Path to select the appropriate entries
408
+ * @property {String} mapping.labelTemplate="" template with the label placeholders in the form ${name}, where name is the key (**)
409
+ * @property {String} mapping.valueTemplate="" template with the value placeholders in the form ${name}, where name is the key
410
+ * @property {Monster.Components.Form~exampleFilterCallback|undefined} mapping.filter Filtering of values via a function
411
+ * @property {Object} formatter
412
+ * @property {Monster.Components.Form~formatterSelectionCallback|undefined} formatter.selection format selection label
413
+ */
414
+ get defaults() {
415
+ return Object.assign(
416
+ {},
417
+ super.defaults,
418
+ {
419
+ toggleEventType: ["click", "touch"],
420
+ delegatesFocus: false,
421
+ options: [],
422
+ selection: [],
423
+ showMaxOptions: 10,
424
+ type: "radio",
425
+ name: new ID("s").toString(),
426
+ features: {
427
+ clearAll: true,
428
+ clear: true,
429
+ lazyLoad: false,
430
+ closeOnSelect: false,
431
+ emptyValueIfNoOptions: false,
432
+ storeFetchedData: false,
433
+ useStrictValueComparison: false,
434
+ },
435
+ url: null,
436
+ lookup: {
437
+ url: null,
438
+ grouping: false,
439
+ },
440
+ labels: {
441
+ "cannot-be-loaded": "Cannot be loaded",
442
+ "no-options-available": noOptionsAvailableMessage,
443
+ "click-to-load-options": clickToLoadOptionsMessage,
444
+ "select-an-option": "Select an option",
445
+ "summary-text": {
446
+ zero: "No entries were selected",
447
+ one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
448
+ other:
449
+ '<span class="monster-badge-primary-pill">${count}</span> entries were selected',
450
+ },
451
+ "no-options":
452
+ "Unfortunately, there are no options available in the list.",
453
+ "no-options-found":
454
+ "No options are available in the list. Please consider modifying the filter.",
455
+ },
456
+ messages: {
457
+ control: null,
458
+ selected: null,
459
+ emptyOptions: null,
460
+ },
461
+ fetch: {
462
+ redirect: "error",
463
+ method: "GET",
464
+ mode: "same-origin",
465
+ credentials: "same-origin",
466
+ headers: {
467
+ accept: "application/json",
468
+ },
469
+ },
470
+ filter: {
471
+ defaultValue: null,
472
+ mode: FILTER_MODE_DISABLED,
473
+ position: FILTER_POSITION_INLINE,
474
+ marker: {
475
+ open: "{",
476
+ close: "}",
477
+ },
478
+ },
479
+ classes: {
480
+ badge: "monster-badge-primary",
481
+ statusOrRemoveBadge: "empty",
482
+ },
483
+ mapping: {
484
+ selector: "*",
485
+ labelTemplate: "",
486
+ valueTemplate: "",
487
+ filter: null,
488
+ },
489
+ formatter: {
490
+ selection: buildSelectionLabel,
491
+ },
492
+ templates: {
493
+ main: getTemplate(),
494
+ },
495
+ templateMapping: {
496
+ /** with the attribute `data-monster-selected-template` the template for the selected options can be defined. */
497
+ selected: getSelectionTemplate(),
498
+ },
499
+
500
+ popper: {
501
+ placement: "bottom",
502
+ middleware: ["flip", "offset:1"],
503
+ },
504
+ },
505
+ initOptionsFromArguments.call(this),
506
+ );
507
+ }
508
+
509
+ /**
510
+ * @return {Select}
511
+ */
512
+ [assembleMethodSymbol]() {
513
+ const self = this;
514
+ super[assembleMethodSymbol]();
515
+
516
+ initControlReferences.call(self);
517
+ initEventHandler.call(self);
518
+
519
+ let lazyLoadFlag = self.getOption("features.lazyLoad", false);
520
+ let remoteFilterFlag = getFilterMode.call(this) === FILTER_MODE_REMOTE;
521
+
522
+ if (getFilterMode.call(this) === FILTER_MODE_REMOTE) {
523
+ self.getOption("features.lazyLoad", false);
524
+ if (lazyLoadFlag === true) {
525
+ addAttributeToken(
526
+ this,
527
+ ATTRIBUTE_ERRORMESSAGE,
528
+ "lazyLoad is not supported with remote filter",
529
+ );
530
+ lazyLoadFlag = false;
531
+ }
532
+ }
533
+
534
+ if (self.hasAttribute("value")) {
535
+ new Processing(10, () => {
536
+ this.value = this.getAttribute("value");
537
+ })
538
+ .run()
539
+ .catch((e) => {
540
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
541
+ });
542
+ }
543
+
544
+ if (self.getOption("url") !== null) {
545
+ if (lazyLoadFlag || remoteFilterFlag) {
546
+ lookupSelection.call(self);
547
+ } else {
548
+ self.fetch().catch((e) => {
549
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
550
+ });
551
+ }
552
+ }
553
+
554
+ let lastValue = self.value;
555
+ self[internalSymbol].attachObserver(
556
+ new Observer(function () {
557
+ if (isObject(this) && this instanceof ProxyObserver) {
558
+ const n = this.getSubject()?.options?.value;
559
+
560
+ if (lastValue !== n) {
561
+ lastValue = n;
562
+ setSelection
563
+ .call(self, n)
564
+ .then(() => {})
565
+ .catch((e) => {
566
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
567
+ });
568
+ }
569
+ }
570
+ }),
571
+ );
572
+
573
+ areOptionsAvailableAndInit.call(self);
574
+
575
+ return this;
576
+ }
577
+
578
+ /**
579
+ *
580
+ * @return {*}
581
+ * @throws {Error} storeFetchedData is not enabled
582
+ * @since 3.66.0
583
+ */
584
+ getLastFetchedData() {
585
+ if (this.getOption("features.storeFetchedData") === false) {
586
+ throw new Error("storeFetchedData is not enabled");
587
+ }
588
+
589
+ return this?.[lastFetchedDataSymbol];
590
+ }
591
+
592
+ /**
593
+ * The Button.click() method simulates a click on the internal button element.
594
+ *
595
+ * @since 3.27.0
596
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
597
+ */
598
+ click() {
599
+ if (this.getOption("disabled") === true) {
600
+ return;
601
+ }
602
+
603
+ toggle.call(this);
604
+ }
605
+
606
+ /**
607
+ * The Button.focus() method sets focus on the internal button element.
608
+ *
609
+ * @since 3.27.0
610
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
611
+ */
612
+ focus(options) {
613
+ if (this.getOption("disabled") === true) {
614
+ return;
615
+ }
616
+
617
+ new Processing(() => {
618
+ gatherState.call(this);
619
+ focusFilter.call(this, options);
620
+ })
621
+ .run()
622
+ .catch((e) => {
623
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
624
+ });
625
+ }
626
+
627
+ /**
628
+ * The Button.blur() method removes focus from the internal button element.
629
+ * @link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur
630
+ */
631
+ blur() {
632
+ new Processing(() => {
633
+ gatherState.call(this);
634
+ blurFilter.call(this);
635
+ })
636
+ .run()
637
+ .catch((e) => {
638
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
639
+ });
640
+ }
641
+
642
+ /**
643
+ * If no url is specified, the options are taken from the Component itself.
644
+ *
645
+ * @param {string|URL} url URL to fetch the options
646
+ * @return {Promise}
647
+ */
648
+ fetch(url) {
649
+ return fetchIt.call(this, url);
650
+ }
651
+
652
+ /**
653
+ * @return {void}
654
+ */
655
+ connectedCallback() {
656
+ super.connectedCallback();
657
+ const document = getDocument();
658
+
659
+ for (const [, type] of Object.entries(["click", "touch"])) {
660
+ // close on outside ui-events
661
+ document.addEventListener(type, this[closeEventHandler]);
662
+ }
663
+
664
+ parseSlotsToOptions.call(this);
665
+ attachResizeObserver.call(this);
666
+ updatePopper.call(this);
667
+
668
+ new Processing(() => {
669
+ gatherState.call(this);
670
+ focusFilter.call(this);
671
+ })
672
+ .run()
673
+ .catch((e) => {
674
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
675
+ });
676
+ }
677
+
678
+ /**
679
+ * @return {void}
680
+ */
681
+ disconnectedCallback() {
682
+ super.disconnectedCallback();
683
+ const document = getDocument();
684
+
685
+ // close on outside ui-events
686
+ for (const [, type] of Object.entries(["click", "touch"])) {
687
+ document.removeEventListener(type, this[closeEventHandler]);
688
+ }
689
+
690
+ disconnectResizeObserver.call(this);
691
+ }
692
+
693
+ /**
694
+ * Import Select Options from dataset
695
+ * Not to be confused with the control defaults/options
696
+ *
697
+ * @param {array|object|Map|Set} data
698
+ * @return {Select}
699
+ * @throws {Error} map is not iterable
700
+ * @throws {Error} missing label configuration
701
+ * @fires monster-options-set this event is fired when the options are set
702
+ */
703
+ importOptions(data) {
704
+ const mappingOptions = this.getOption("mapping", {});
705
+ const selector = mappingOptions?.["selector"];
706
+ const labelTemplate = mappingOptions?.["labelTemplate"];
707
+ const valueTemplate = mappingOptions?.["valueTemplate"];
708
+ const filter = mappingOptions?.["filter"];
709
+
710
+ let flag = false;
711
+ if (labelTemplate === "") {
712
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty label template");
713
+ flag = true;
714
+ }
715
+
716
+ if (valueTemplate === "") {
717
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty value template");
718
+ flag = true;
719
+ }
720
+
721
+ if (flag === true) {
722
+ throw new Error("missing label configuration");
723
+ }
724
+
725
+ const map = buildMap(data, selector, labelTemplate, valueTemplate, filter);
726
+
727
+ const options = [];
728
+
729
+ if (!isIterable(map)) {
730
+ throw new Error("map is not iterable");
731
+ }
732
+
733
+ const visibility = "visible";
734
+
735
+ map.forEach((label, value) => {
736
+ options.push({
737
+ value,
738
+ label,
739
+ visibility,
740
+ data: map.get(value),
741
+ });
742
+ });
743
+
744
+ runAsOptionLengthChanged.call(this, map.size);
745
+ this.setOption("options", options);
746
+
747
+ fireCustomEvent(this, "monster-options-set", {
748
+ options,
749
+ });
750
+
751
+ return this;
752
+ }
753
+
754
+ /**
755
+ * @private
756
+ * @return {Select}
757
+ */
758
+ calcAndSetOptionsDimension() {
759
+ calcAndSetOptionsDimension.call(this);
760
+ return this;
761
+ }
762
+
763
+ /**
764
+ *
765
+ * @return {string}
766
+ */
767
+ static getTag() {
768
+ return "monster-select";
769
+ }
770
+
771
+ /**
772
+ *
773
+ * @return {CSSStyleSheet[]}
774
+ */
775
+ static getCSSStyleSheet() {
776
+ return [SelectStyleSheet];
777
+ }
773
778
  }
774
779
 
780
+ /**
781
+ * @private
782
+ */
775
783
  function lookupSelection() {
776
- const self = this;
777
-
778
- setTimeout(() => {
779
- const selection = self.getOption("selection");
780
- if (selection.length === 0) {
781
- return;
782
- }
783
-
784
- if (self[isLoadingSymbol] === true) {
785
- return;
786
- }
787
-
788
- if (self[lazyLoadDoneSymbol] === true) {
789
- return;
790
- }
791
-
792
- let url = self.getOption("url");
793
- let lookupUrl = self.getOption("lookup.url");
794
- if (lookupUrl !== null) {
795
- url = lookupUrl;
796
- }
797
-
798
- if (this.getOption("lookup.grouping") === true) {
799
- filterFromRemoteByValue.call(
800
- self,
801
- url,
802
- selection.map((s) => s?.["value"]),
803
- );
804
- return;
805
- }
806
-
807
- for (const s of selection) {
808
- if (s?.["value"]) {
809
- filterFromRemoteByValue.call(self, url, s?.["value"]);
810
- }
811
- }
812
- }, 100);
784
+ const self = this;
785
+
786
+ setTimeout(() => {
787
+ const selection = self.getOption("selection");
788
+ if (selection.length === 0) {
789
+ return;
790
+ }
791
+
792
+ if (self[isLoadingSymbol] === true) {
793
+ return;
794
+ }
795
+
796
+ if (self[lazyLoadDoneSymbol] === true) {
797
+ return;
798
+ }
799
+
800
+ let url = self.getOption("url");
801
+ let lookupUrl = self.getOption("lookup.url");
802
+ if (lookupUrl !== null) {
803
+ url = lookupUrl;
804
+ }
805
+
806
+ if (this.getOption("lookup.grouping") === true) {
807
+ filterFromRemoteByValue
808
+ .call(
809
+ self,
810
+ url,
811
+ selection.map((s) => s?.["value"]),
812
+ )
813
+ .catch((e) => {
814
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
815
+ });
816
+ return;
817
+ }
818
+
819
+ for (const s of selection) {
820
+ if (s?.["value"]) {
821
+ filterFromRemoteByValue.call(self, url, s?.["value"]).catch((e) => {
822
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
823
+ });
824
+ }
825
+ }
826
+ }, 100);
813
827
  }
814
828
 
815
829
  function fetchIt(url, controlOptions) {
816
- if (url instanceof URL) {
817
- url = url.toString();
818
- }
819
-
820
- if (url !== undefined && url !== null) {
821
- url = validateString(url);
822
- } else {
823
- url = this.getOption("url");
824
- if (url === null) {
825
- return Promise.reject(new Error("No url defined"));
826
- }
827
- }
828
-
829
- return new Promise((resolve, reject) => {
830
- setStatusOrRemoveBadges.call(this, "loading");
831
-
832
- new Processing(10, () => {
833
-
834
- fetchData
835
- .call(this, url)
836
- .then((map) => {
837
- if (
838
- isObject(map) ||
839
- isArray(map) ||
840
- map instanceof Set ||
841
- map instanceof Map
842
- ) {
843
- try {
844
- this.importOptions(map);
845
- } catch (e) {
846
- setStatusOrRemoveBadges.call(this, "error");
847
- reject(e);
848
- return;
849
- }
850
-
851
- this[lastFetchedDataSymbol] = map;
852
-
853
- let result;
854
- const selection = this.getOption("selection");
855
- let newValue = [];
856
- if (selection) {
857
- newValue = selection;
858
- } else if (this.hasAttribute("value")) {
859
- newValue = this.getAttribute("value");
860
- }
861
-
862
- result = setSelection.call(this, newValue);
863
- requestAnimationFrame(() => {
864
- checkOptionState.call(this);
865
- setStatusOrRemoveBadges.call(this, "closed");
866
- updatePopper.call(this);
867
- resolve(result);
868
- });
869
-
870
- return;
871
- }
872
-
873
- setStatusOrRemoveBadges.call(this, "error");
874
- reject(new Error("invalid response"));
875
- })
876
- .catch((e) => {
877
- setStatusOrRemoveBadges.call(this, "error");
878
- reject(e);
879
- });
880
- })
881
- .run()
882
- .catch((e) => {
883
- setStatusOrRemoveBadges.call(this, "error");
884
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
885
- reject(e);
886
- });
887
- });
830
+ if (url instanceof URL) {
831
+ url = url.toString();
832
+ }
833
+
834
+ if (url !== undefined && url !== null) {
835
+ url = validateString(url);
836
+ } else {
837
+ url = this.getOption("url");
838
+ if (url === null) {
839
+ return Promise.reject(new Error("No url defined"));
840
+ }
841
+ }
842
+
843
+ return new Promise((resolve, reject) => {
844
+ setStatusOrRemoveBadges.call(this, "loading");
845
+
846
+ new Processing(10, () => {
847
+ fetchData
848
+ .call(this, url)
849
+ .then((map) => {
850
+ if (
851
+ isObject(map) ||
852
+ isArray(map) ||
853
+ map instanceof Set ||
854
+ map instanceof Map
855
+ ) {
856
+ try {
857
+ this.importOptions(map);
858
+ } catch (e) {
859
+ setStatusOrRemoveBadges.call(this, "error");
860
+ reject(e);
861
+ return;
862
+ }
863
+
864
+ this[lastFetchedDataSymbol] = map;
865
+
866
+ let result;
867
+ const selection = this.getOption("selection");
868
+ let newValue = [];
869
+ if (selection) {
870
+ newValue = selection;
871
+ } else if (this.hasAttribute("value")) {
872
+ newValue = this.getAttribute("value");
873
+ }
874
+
875
+ result = setSelection.call(this, newValue);
876
+ requestAnimationFrame(() => {
877
+ checkOptionState.call(this);
878
+ setStatusOrRemoveBadges.call(this, "closed");
879
+ updatePopper.call(this);
880
+ resolve(result);
881
+ });
882
+
883
+ return;
884
+ }
885
+
886
+ setStatusOrRemoveBadges.call(this, "error");
887
+ reject(new Error("invalid response"));
888
+ })
889
+ .catch((e) => {
890
+ setStatusOrRemoveBadges.call(this, "error");
891
+ reject(e);
892
+ });
893
+ })
894
+ .run()
895
+ .catch((e) => {
896
+ setStatusOrRemoveBadges.call(this, "error");
897
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
898
+ reject(e);
899
+ });
900
+ });
888
901
  }
889
902
 
890
903
  /**
@@ -899,64 +912,64 @@ function fetchIt(url, controlOptions) {
899
912
  * @return {object}
900
913
  */
901
914
  function initOptionsFromArguments() {
902
- const options = {};
903
-
904
- const template = this.getAttribute("data-monster-selected-template");
905
- if (isString(template)) {
906
- if (!options["templateMapping"]) options["templateMapping"] = {};
907
-
908
- switch (template) {
909
- case "summary":
910
- case "default":
911
- options["templateMapping"]["selected"] = getSummaryTemplate();
912
- break;
913
- case "selected":
914
- options["templateMapping"]["selected"] = getSelectionTemplate();
915
- break;
916
- default:
917
- addAttributeToken(
918
- this,
919
- ATTRIBUTE_ERRORMESSAGE,
920
- "invalid template, use summary or selected",
921
- );
922
- }
923
- }
924
-
925
- return options;
915
+ const options = {};
916
+
917
+ const template = this.getAttribute("data-monster-selected-template");
918
+ if (isString(template)) {
919
+ if (!options["templateMapping"]) options["templateMapping"] = {};
920
+
921
+ switch (template) {
922
+ case "summary":
923
+ case "default":
924
+ options["templateMapping"]["selected"] = getSummaryTemplate();
925
+ break;
926
+ case "selected":
927
+ options["templateMapping"]["selected"] = getSelectionTemplate();
928
+ break;
929
+ default:
930
+ addAttributeToken(
931
+ this,
932
+ ATTRIBUTE_ERRORMESSAGE,
933
+ "invalid template, use summary or selected",
934
+ );
935
+ }
936
+ }
937
+
938
+ return options;
926
939
  }
927
940
 
928
941
  /**
929
942
  * @private
930
943
  */
931
944
  function attachResizeObserver() {
932
- // against flickering
933
- this[resizeObserverSymbol] = new ResizeObserver((entries) => {
934
- if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
935
- try {
936
- this[timerCallbackSymbol].touch();
937
- return;
938
- } catch (e) {
939
- delete this[timerCallbackSymbol];
940
- }
941
- }
942
-
943
- this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
944
- updatePopper.call(this);
945
- delete this[timerCallbackSymbol];
946
- });
947
- });
948
-
949
- this[resizeObserverSymbol].observe(this.parentElement);
945
+ // against flickering
946
+ this[resizeObserverSymbol] = new ResizeObserver((entries) => {
947
+ if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
948
+ try {
949
+ this[timerCallbackSymbol].touch();
950
+ return;
951
+ } catch (e) {
952
+ delete this[timerCallbackSymbol];
953
+ }
954
+ }
955
+
956
+ this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
957
+ updatePopper.call(this);
958
+ delete this[timerCallbackSymbol];
959
+ });
960
+ });
961
+
962
+ this[resizeObserverSymbol].observe(this.parentElement);
950
963
  }
951
964
 
952
965
  function disconnectResizeObserver() {
953
- if (this[resizeObserverSymbol] instanceof ResizeObserver) {
954
- this[resizeObserverSymbol].disconnect();
955
- }
966
+ if (this[resizeObserverSymbol] instanceof ResizeObserver) {
967
+ this[resizeObserverSymbol].disconnect();
968
+ }
956
969
  }
957
970
 
958
971
  function getSelectionTemplate() {
959
- return `<div data-monster-role="selection"
972
+ return `<div data-monster-role="selection"
960
973
  data-monster-insert="selection path:selection" role="search"
961
974
  ><input type="text" role="searchbox"
962
975
  part="inline-filter" name="inline-filter"
@@ -968,7 +981,7 @@ function getSelectionTemplate() {
968
981
  }
969
982
 
970
983
  function getSummaryTemplate() {
971
- return `<div data-monster-role="selection" role="search">
984
+ return `<div data-monster-role="selection" role="search">
972
985
  <input type="text" role="searchbox"
973
986
  part="inline-filter" name="inline-filter"
974
987
  data-monster-role="filter"
@@ -984,35 +997,35 @@ function getSummaryTemplate() {
984
997
  * @private
985
998
  */
986
999
  function parseSlotsToOptions() {
987
- let options = this.getOption("options");
988
- if (!isIterable(options)) {
989
- options = [];
990
- }
991
-
992
- let counter = 1;
993
- getSlottedElements.call(this, "div").forEach((node) => {
994
- let value = (counter++).toString();
995
- let visibility = "visible";
996
-
997
- if (node.hasAttribute("data-monster-value")) {
998
- value = node.getAttribute("data-monster-value");
999
- }
1000
-
1001
- if (node.style.display === "none") {
1002
- visibility = "hidden";
1003
- }
1004
-
1005
- const label = node.outerHTML;
1006
-
1007
- options.push({
1008
- value,
1009
- label,
1010
- visibility,
1011
- });
1012
- });
1013
-
1014
- runAsOptionLengthChanged.call(this, options.length);
1015
- this.setOption("options", options);
1000
+ let options = this.getOption("options");
1001
+ if (!isIterable(options)) {
1002
+ options = [];
1003
+ }
1004
+
1005
+ let counter = 1;
1006
+ getSlottedElements.call(this, "div").forEach((node) => {
1007
+ let value = (counter++).toString();
1008
+ let visibility = "visible";
1009
+
1010
+ if (node.hasAttribute("data-monster-value")) {
1011
+ value = node.getAttribute("data-monster-value");
1012
+ }
1013
+
1014
+ if (node.style.display === "none") {
1015
+ visibility = "hidden";
1016
+ }
1017
+
1018
+ const label = node.outerHTML;
1019
+
1020
+ options.push({
1021
+ value,
1022
+ label,
1023
+ visibility,
1024
+ });
1025
+ });
1026
+
1027
+ runAsOptionLengthChanged.call(this, options.length);
1028
+ this.setOption("options", options);
1016
1029
  }
1017
1030
 
1018
1031
  /**
@@ -1022,39 +1035,39 @@ function parseSlotsToOptions() {
1022
1035
  * @param {int} targetLength
1023
1036
  */
1024
1037
  function runAsOptionLengthChanged(targetLength) {
1025
- const self = this;
1026
-
1027
- if (!self[optionsElementSymbol]) {
1028
- return;
1029
- }
1030
-
1031
- const callback = function (mutationsList, observer) {
1032
- const run = false;
1033
- for (const mutation of mutationsList) {
1034
- if (mutation.type === "childList") {
1035
- const run = true;
1036
- break;
1037
- }
1038
- }
1039
-
1040
- if (run === true) {
1041
- const nodes = self[optionsElementSymbol].querySelectorAll(
1042
- `div[${ATTRIBUTE_ROLE}=option]`,
1043
- );
1044
-
1045
- if (nodes.length === targetLength) {
1046
- checkOptionState.call(self);
1047
- observer.disconnect();
1048
- }
1049
- }
1050
- };
1051
-
1052
- const observer = new MutationObserver(callback);
1053
- observer.observe(self[optionsElementSymbol], {
1054
- attributes: false,
1055
- childList: true,
1056
- subtree: true,
1057
- });
1038
+ const self = this;
1039
+
1040
+ if (!self[optionsElementSymbol]) {
1041
+ return;
1042
+ }
1043
+
1044
+ const callback = function (mutationsList, observer) {
1045
+ const run = false;
1046
+ for (const mutation of mutationsList) {
1047
+ if (mutation.type === "childList") {
1048
+ const run = true;
1049
+ break;
1050
+ }
1051
+ }
1052
+
1053
+ if (run === true) {
1054
+ const nodes = self[optionsElementSymbol].querySelectorAll(
1055
+ `div[${ATTRIBUTE_ROLE}=option]`,
1056
+ );
1057
+
1058
+ if (nodes.length === targetLength) {
1059
+ checkOptionState.call(self);
1060
+ observer.disconnect();
1061
+ }
1062
+ }
1063
+ };
1064
+
1065
+ const observer = new MutationObserver(callback);
1066
+ observer.observe(self[optionsElementSymbol], {
1067
+ attributes: false,
1068
+ childList: true,
1069
+ subtree: true,
1070
+ });
1058
1071
  }
1059
1072
 
1060
1073
  /**
@@ -1063,38 +1076,38 @@ function runAsOptionLengthChanged(targetLength) {
1063
1076
  * @return {*}
1064
1077
  */
1065
1078
  function buildSelectionLabel(value) {
1066
- const options = this.getOption("options");
1067
-
1068
- for (let i = 0; i < options.length; i++) {
1069
- let o = options?.[i];
1070
- let l, v, v2;
1071
-
1072
- if (this.getOption("features.useStrictValueComparison") === true) {
1073
- v = value;
1074
- } else {
1075
- v = `${value}`;
1076
- }
1077
-
1078
- if (isPrimitive(o) && o === value) {
1079
- return o;
1080
- } else if (!isObject(o)) {
1081
- continue;
1082
- }
1083
-
1084
- if (this.getOption("features.useStrictValueComparison") === true) {
1085
- l = o?.["label"];
1086
- v2 = o?.["value"];
1087
- } else {
1088
- l = `${o?.["label"]}`;
1089
- v2 = `${o?.["value"]}`;
1090
- }
1091
-
1092
- if (v2 === v) {
1093
- return l;
1094
- }
1095
- }
1096
-
1097
- return undefined;
1079
+ const options = this.getOption("options");
1080
+
1081
+ for (let i = 0; i < options.length; i++) {
1082
+ let o = options?.[i];
1083
+ let l, v, v2;
1084
+
1085
+ if (this.getOption("features.useStrictValueComparison") === true) {
1086
+ v = value;
1087
+ } else {
1088
+ v = `${value}`;
1089
+ }
1090
+
1091
+ if (isPrimitive(o) && o === value) {
1092
+ return o;
1093
+ } else if (!isObject(o)) {
1094
+ continue;
1095
+ }
1096
+
1097
+ if (this.getOption("features.useStrictValueComparison") === true) {
1098
+ l = o?.["label"];
1099
+ v2 = o?.["value"];
1100
+ } else {
1101
+ l = `${o?.["label"]}`;
1102
+ v2 = `${o?.["value"]}`;
1103
+ }
1104
+
1105
+ if (v2 === v) {
1106
+ return l;
1107
+ }
1108
+ }
1109
+
1110
+ return undefined;
1098
1111
  }
1099
1112
 
1100
1113
  /**
@@ -1104,17 +1117,17 @@ function buildSelectionLabel(value) {
1104
1117
  * @throws {Error} no value found
1105
1118
  */
1106
1119
  function getSelectionLabel(value) {
1107
- const callback = this.getOption("formatter.selection");
1108
- if (isFunction(callback)) {
1109
- const label = callback.call(this, value);
1110
- if (isString(label)) return label;
1111
- }
1120
+ const callback = this.getOption("formatter.selection");
1121
+ if (isFunction(callback)) {
1122
+ const label = callback.call(this, value);
1123
+ if (isString(label)) return label;
1124
+ }
1112
1125
 
1113
- if (isString(value) || isInteger(value)) {
1114
- return `${value}`;
1115
- }
1126
+ if (isString(value) || isInteger(value)) {
1127
+ return `${value}`;
1128
+ }
1116
1129
 
1117
- return this.getOption("labels.cannot-be-loaded", value);
1130
+ return this.getOption("labels.cannot-be-loaded", value);
1118
1131
  }
1119
1132
 
1120
1133
  /**
@@ -1122,25 +1135,25 @@ function getSelectionLabel(value) {
1122
1135
  * @param {Event} event
1123
1136
  */
1124
1137
  function handleToggleKeyboardEvents(event) {
1125
- switch (event?.["code"]) {
1126
- case "Escape":
1127
- toggle.call(this);
1128
- event.preventDefault();
1129
- break;
1130
- case "Space":
1131
- toggle.call(this);
1132
- event.preventDefault();
1133
- break;
1134
- case "ArrowDown":
1135
- show.call(this);
1136
- activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1137
- event.preventDefault();
1138
- break;
1139
- case "ArrowUp":
1140
- hide.call(this);
1141
- event.preventDefault();
1142
- break;
1143
- }
1138
+ switch (event?.["code"]) {
1139
+ case "Escape":
1140
+ toggle.call(this);
1141
+ event.preventDefault();
1142
+ break;
1143
+ case "Space":
1144
+ toggle.call(this);
1145
+ event.preventDefault();
1146
+ break;
1147
+ case "ArrowDown":
1148
+ show.call(this);
1149
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1150
+ event.preventDefault();
1151
+ break;
1152
+ case "ArrowUp":
1153
+ hide.call(this);
1154
+ event.preventDefault();
1155
+ break;
1156
+ }
1144
1157
  }
1145
1158
 
1146
1159
  /**
@@ -1150,46 +1163,45 @@ function handleToggleKeyboardEvents(event) {
1150
1163
  * @this CustomElement
1151
1164
  */
1152
1165
  function initOptionObserver() {
1153
- const self = this;
1154
-
1155
- self.attachObserver(
1156
- new Observer(function () {
1157
- new Processing(() => {
1158
- try {
1159
- self.updateI18n();
1160
- } catch (e) {
1161
- console.error(e);
1162
- requestAnimationFrame(() => {
1163
- setStatusOrRemoveBadges.call(self, "error");
1164
- });
1165
- }
1166
- try {
1167
- areOptionsAvailableAndInit.call(self);
1168
- } catch (e) {
1169
- console.error(e);
1170
- requestAnimationFrame(() => {
1171
- setStatusOrRemoveBadges.call(self, "error");
1172
- });
1173
- }
1174
-
1175
- setSummaryAndControlText.call(self);
1176
- }).run();
1177
- }),
1178
- );
1166
+ const self = this;
1167
+
1168
+ self.attachObserver(
1169
+ new Observer(function () {
1170
+ new Processing(() => {
1171
+ try {
1172
+ self.updateI18n();
1173
+ } catch (e) {
1174
+ console.error(e);
1175
+ requestAnimationFrame(() => {
1176
+ setStatusOrRemoveBadges.call(self, "error");
1177
+ });
1178
+ }
1179
+ try {
1180
+ areOptionsAvailableAndInit.call(self);
1181
+ } catch (e) {
1182
+ console.error(e);
1183
+ requestAnimationFrame(() => {
1184
+ setStatusOrRemoveBadges.call(self, "error");
1185
+ });
1186
+ }
1187
+
1188
+ setSummaryAndControlText.call(self);
1189
+ }).run();
1190
+ }),
1191
+ );
1179
1192
  }
1180
1193
 
1181
1194
  function getDefaultTranslation() {
1182
- const translation = new Translations("en").assignTranslations(
1183
- this.getOption("labels", {}),
1184
- );
1195
+ const translation = new Translations("en").assignTranslations(
1196
+ this.getOption("labels", {}),
1197
+ );
1185
1198
 
1186
- try {
1187
- const doc = getDocumentTranslations();
1188
- translation.locale = doc.locale;
1189
- } catch (e) {
1190
- }
1199
+ try {
1200
+ const doc = getDocumentTranslations();
1201
+ translation.locale = doc.locale;
1202
+ } catch (e) {}
1191
1203
 
1192
- return translation;
1204
+ return translation;
1193
1205
  }
1194
1206
 
1195
1207
  /**
@@ -1197,36 +1209,36 @@ function getDefaultTranslation() {
1197
1209
  * @return {string|*}
1198
1210
  */
1199
1211
  function setSummaryAndControlText() {
1200
- const translations = getDefaultTranslation.call(this);
1201
- const selections = this.getOption("selection");
1202
-
1203
- const text = translations.getPluralRuleText(
1204
- "summary-text",
1205
- selections.length,
1206
- "",
1207
- );
1208
-
1209
- const selectedText = new Formatter({
1210
- count: String(selections.length),
1211
- }).format(text);
1212
-
1213
- this.setOption("messages.selected", selectedText);
1214
-
1215
- const current = this.getOption("messages.control");
1216
- const msg = this.getOption("labels.select-an-option");
1217
-
1218
- if (
1219
- current === "" ||
1220
- current === undefined ||
1221
- current === msg ||
1222
- current === null
1223
- ) {
1224
- if (selections === undefined || selections.length === 0) {
1225
- this.setOption("messages.control", msg);
1226
- } else {
1227
- this.setOption("messages.control", "");
1228
- }
1229
- }
1212
+ const translations = getDefaultTranslation.call(this);
1213
+ const selections = this.getOption("selection");
1214
+
1215
+ const text = translations.getPluralRuleText(
1216
+ "summary-text",
1217
+ selections.length,
1218
+ "",
1219
+ );
1220
+
1221
+ const selectedText = new Formatter({
1222
+ count: String(selections.length),
1223
+ }).format(text);
1224
+
1225
+ this.setOption("messages.selected", selectedText);
1226
+
1227
+ const current = this.getOption("messages.control");
1228
+ const msg = this.getOption("labels.select-an-option");
1229
+
1230
+ if (
1231
+ current === "" ||
1232
+ current === undefined ||
1233
+ current === msg ||
1234
+ current === null
1235
+ ) {
1236
+ if (selections === undefined || selections.length === 0) {
1237
+ this.setOption("messages.control", msg);
1238
+ } else {
1239
+ this.setOption("messages.control", "");
1240
+ }
1241
+ }
1230
1242
  }
1231
1243
 
1232
1244
  /**
@@ -1234,9 +1246,9 @@ function setSummaryAndControlText() {
1234
1246
  * @return {NodeList}
1235
1247
  */
1236
1248
  function getOptionElements() {
1237
- return this[optionsElementSymbol].querySelectorAll(
1238
- `[${ATTRIBUTE_ROLE}=option]`,
1239
- );
1249
+ return this[optionsElementSymbol].querySelectorAll(
1250
+ `[${ATTRIBUTE_ROLE}=option]`,
1251
+ );
1240
1252
  }
1241
1253
 
1242
1254
  /**
@@ -1262,75 +1274,75 @@ function getOptionElements() {
1262
1274
  * @private
1263
1275
  */
1264
1276
  function calcAndSetOptionsDimension() {
1265
- const options = getOptionElements.call(this);
1266
- const container = this[optionsElementSymbol];
1267
- if (!(container instanceof HTMLElement && options instanceof NodeList)) {
1268
- return;
1269
- }
1270
-
1271
- let visible = 0;
1272
- let optionHeight = 0;
1273
- const max = this.getOption("showMaxOptions", 10);
1274
-
1275
- let scrollFlag = false;
1276
- for (const [, option] of Object.entries(options)) {
1277
- const computedStyle = getGlobal().getComputedStyle(option);
1278
- if (computedStyle.display === "none") continue;
1279
-
1280
- let h = option.getBoundingClientRect().height;
1281
- h += parseInt(computedStyle.getPropertyValue("margin-top"), 10);
1282
- h += parseInt(computedStyle.getPropertyValue("margin-bottom"), 10);
1283
- optionHeight += h;
1284
-
1285
- visible++;
1286
-
1287
- if (visible > max) {
1288
- break;
1289
- }
1290
- }
1291
-
1292
- if (visible > max) {
1293
- visible = max;
1294
- scrollFlag = true;
1295
- }
1296
-
1297
- if (visible === 0) {
1298
- if (this.getOption("filter.mode") === FILTER_MODE_DISABLED) {
1299
- this.setOption(
1300
- "messages.emptyOptions",
1301
- this.getOption("labels.no-options-available"),
1302
- );
1303
- } else {
1304
- this.setOption(
1305
- "messages.emptyOptions",
1306
- this.getOption("labels.no-options-found"),
1307
- );
1308
- }
1309
- this[noOptionsAvailableElementSymbol].classList.remove("d-none");
1310
- } else {
1311
- this[noOptionsAvailableElementSymbol].classList.add("d-none");
1312
- }
1313
-
1314
- const styles = getGlobal().getComputedStyle(this[optionsElementSymbol]);
1315
- let padding = parseInt(styles.getPropertyValue("padding-top"), 10);
1316
- padding += parseInt(styles.getPropertyValue("padding-bottom"), 10);
1317
-
1318
- let margin = parseInt(styles.getPropertyValue("margin-top"), 10);
1319
- margin += parseInt(styles.getPropertyValue("margin-bottom"), 10);
1320
-
1321
- const containerHeight = optionHeight + padding + margin;
1322
- container.style.height = `${containerHeight}px`;
1323
-
1324
- if (scrollFlag === true) {
1325
- container.style.overflowY = "scroll";
1326
- } else {
1327
- container.style.overflowY = "auto";
1328
- }
1329
-
1330
- const domRect = this[controlElementSymbol].getBoundingClientRect();
1331
-
1332
- this[popperElementSymbol].style.width = `${domRect.width}px`;
1333
- container.style.overflowX = "auto";
1277
+ const options = getOptionElements.call(this);
1278
+ const container = this[optionsElementSymbol];
1279
+ if (!(container instanceof HTMLElement && options instanceof NodeList)) {
1280
+ return;
1281
+ }
1282
+
1283
+ let visible = 0;
1284
+ let optionHeight = 0;
1285
+ const max = this.getOption("showMaxOptions", 10);
1286
+
1287
+ let scrollFlag = false;
1288
+ for (const [, option] of Object.entries(options)) {
1289
+ const computedStyle = getGlobal().getComputedStyle(option);
1290
+ if (computedStyle.display === "none") continue;
1291
+
1292
+ let h = option.getBoundingClientRect().height;
1293
+ h += parseInt(computedStyle.getPropertyValue("margin-top"), 10);
1294
+ h += parseInt(computedStyle.getPropertyValue("margin-bottom"), 10);
1295
+ optionHeight += h;
1296
+
1297
+ visible++;
1298
+
1299
+ if (visible > max) {
1300
+ break;
1301
+ }
1302
+ }
1303
+
1304
+ if (visible > max) {
1305
+ visible = max;
1306
+ scrollFlag = true;
1307
+ }
1308
+
1309
+ if (visible === 0) {
1310
+ if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1311
+ this.setOption(
1312
+ "messages.emptyOptions",
1313
+ this.getOption("labels.no-options-available"),
1314
+ );
1315
+ } else {
1316
+ this.setOption(
1317
+ "messages.emptyOptions",
1318
+ this.getOption("labels.no-options-found"),
1319
+ );
1320
+ }
1321
+ this[noOptionsAvailableElementSymbol].classList.remove("d-none");
1322
+ } else {
1323
+ this[noOptionsAvailableElementSymbol].classList.add("d-none");
1324
+ }
1325
+
1326
+ const styles = getGlobal().getComputedStyle(this[optionsElementSymbol]);
1327
+ let padding = parseInt(styles.getPropertyValue("padding-top"), 10);
1328
+ padding += parseInt(styles.getPropertyValue("padding-bottom"), 10);
1329
+
1330
+ let margin = parseInt(styles.getPropertyValue("margin-top"), 10);
1331
+ margin += parseInt(styles.getPropertyValue("margin-bottom"), 10);
1332
+
1333
+ const containerHeight = optionHeight + padding + margin;
1334
+ container.style.height = `${containerHeight}px`;
1335
+
1336
+ if (scrollFlag === true) {
1337
+ container.style.overflowY = "scroll";
1338
+ } else {
1339
+ container.style.overflowY = "auto";
1340
+ }
1341
+
1342
+ const domRect = this[controlElementSymbol].getBoundingClientRect();
1343
+
1344
+ this[popperElementSymbol].style.width = `${domRect.width}px`;
1345
+ container.style.overflowX = "auto";
1334
1346
  }
1335
1347
 
1336
1348
  /**
@@ -1339,126 +1351,126 @@ function calcAndSetOptionsDimension() {
1339
1351
  * @throws {Error} no shadow-root is defined
1340
1352
  */
1341
1353
  function activateCurrentOption(direction) {
1342
- if (!this.shadowRoot) {
1343
- throw new Error("no shadow-root is defined");
1344
- }
1345
-
1346
- let focused = this.shadowRoot.querySelector(`[${ATTRIBUTE_PREFIX}focused]`);
1347
-
1348
- if (
1349
- !(focused instanceof HTMLElement) ||
1350
- focused.matches("[data-monster-visibility=hidden]")
1351
- ) {
1352
- for (const [, e] of Object.entries(
1353
- this.shadowRoot.querySelectorAll(`[${ATTRIBUTE_ROLE}=option]`),
1354
- )) {
1355
- if (e.matches("[data-monster-visibility=visible]")) {
1356
- focused = e;
1357
- break;
1358
- }
1359
- }
1360
- } else {
1361
- if (direction === FOCUS_DIRECTION_DOWN) {
1362
- while (focused.nextSibling) {
1363
- focused = focused.nextSibling;
1364
-
1365
- if (
1366
- focused instanceof HTMLElement &&
1367
- focused.hasAttribute(ATTRIBUTE_ROLE) &&
1368
- focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1369
- focused.matches("[data-monster-visibility=visible]") &&
1370
- focused.matches(":not([data-monster-filtered=true])")
1371
- ) {
1372
- break;
1373
- }
1374
- }
1375
- } else {
1376
- let found = false;
1377
- while (focused.previousSibling) {
1378
- focused = focused.previousSibling;
1379
- if (
1380
- focused instanceof HTMLElement &&
1381
- focused.hasAttribute(ATTRIBUTE_ROLE) &&
1382
- focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1383
- focused.matches("[data-monster-visibility=visible]") &&
1384
- focused.matches(":not([data-monster-filtered=true])")
1385
- ) {
1386
- found = true;
1387
- break;
1388
- }
1389
- }
1390
- if (found === false) {
1391
- focusFilter.call(this);
1392
- }
1393
- }
1394
- }
1395
-
1396
- new Processing(() => {
1397
- if (focused instanceof HTMLElement) {
1398
- this.shadowRoot
1399
- .querySelectorAll(`[${ATTRIBUTE_PREFIX}focused]`)
1400
- .forEach((e) => {
1401
- e.removeAttribute(`${ATTRIBUTE_PREFIX}focused`);
1402
- });
1403
-
1404
- focused.focus();
1405
- focused.setAttribute(`${ATTRIBUTE_PREFIX}focused`, true);
1406
- }
1407
- })
1408
- .run()
1409
- .catch((e) => {
1410
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1411
- });
1354
+ if (!this.shadowRoot) {
1355
+ throw new Error("no shadow-root is defined");
1356
+ }
1357
+
1358
+ let focused = this.shadowRoot.querySelector(`[${ATTRIBUTE_PREFIX}focused]`);
1359
+
1360
+ if (
1361
+ !(focused instanceof HTMLElement) ||
1362
+ focused.matches("[data-monster-visibility=hidden]")
1363
+ ) {
1364
+ for (const [, e] of Object.entries(
1365
+ this.shadowRoot.querySelectorAll(`[${ATTRIBUTE_ROLE}=option]`),
1366
+ )) {
1367
+ if (e.matches("[data-monster-visibility=visible]")) {
1368
+ focused = e;
1369
+ break;
1370
+ }
1371
+ }
1372
+ } else {
1373
+ if (direction === FOCUS_DIRECTION_DOWN) {
1374
+ while (focused.nextSibling) {
1375
+ focused = focused.nextSibling;
1376
+
1377
+ if (
1378
+ focused instanceof HTMLElement &&
1379
+ focused.hasAttribute(ATTRIBUTE_ROLE) &&
1380
+ focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1381
+ focused.matches("[data-monster-visibility=visible]") &&
1382
+ focused.matches(":not([data-monster-filtered=true])")
1383
+ ) {
1384
+ break;
1385
+ }
1386
+ }
1387
+ } else {
1388
+ let found = false;
1389
+ while (focused.previousSibling) {
1390
+ focused = focused.previousSibling;
1391
+ if (
1392
+ focused instanceof HTMLElement &&
1393
+ focused.hasAttribute(ATTRIBUTE_ROLE) &&
1394
+ focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1395
+ focused.matches("[data-monster-visibility=visible]") &&
1396
+ focused.matches(":not([data-monster-filtered=true])")
1397
+ ) {
1398
+ found = true;
1399
+ break;
1400
+ }
1401
+ }
1402
+ if (found === false) {
1403
+ focusFilter.call(this);
1404
+ }
1405
+ }
1406
+ }
1407
+
1408
+ new Processing(() => {
1409
+ if (focused instanceof HTMLElement) {
1410
+ this.shadowRoot
1411
+ .querySelectorAll(`[${ATTRIBUTE_PREFIX}focused]`)
1412
+ .forEach((e) => {
1413
+ e.removeAttribute(`${ATTRIBUTE_PREFIX}focused`);
1414
+ });
1415
+
1416
+ focused.focus();
1417
+ focused.setAttribute(`${ATTRIBUTE_PREFIX}focused`, true);
1418
+ }
1419
+ })
1420
+ .run()
1421
+ .catch((e) => {
1422
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1423
+ });
1412
1424
  }
1413
1425
 
1414
1426
  /**
1415
1427
  * @private
1416
1428
  */
1417
1429
  function filterOptions() {
1418
- new Processing(() => {
1419
- let filterValue;
1420
-
1421
- switch (this.getOption("filter.position")) {
1422
- case FILTER_POSITION_INLINE:
1423
- if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
1424
- filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
1425
- } else {
1426
- return;
1427
- }
1428
-
1429
- break;
1430
- case FILTER_POSITION_POPPER:
1431
- default:
1432
- if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
1433
- filterValue = this[popperFilterElementSymbol].value.toLowerCase();
1434
- } else {
1435
- return;
1436
- }
1437
- }
1438
-
1439
- const options = this.getOption("options");
1440
- for (const [i, option] of Object.entries(options)) {
1441
- if (option.label.toLowerCase().indexOf(filterValue) === -1) {
1442
- this.setOption(`options.${i}.filtered`, "true");
1443
- } else {
1444
- this.setOption(`options.${i}.filtered`, undefined);
1445
- }
1446
- }
1447
- })
1448
- .run()
1449
- .then(() => {
1450
- new Processing(100, () => {
1451
- calcAndSetOptionsDimension.call(this);
1452
- focusFilter.call(this);
1453
- })
1454
- .run()
1455
- .catch((e) => {
1456
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1457
- });
1458
- })
1459
- .catch((e) => {
1460
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1461
- });
1430
+ new Processing(() => {
1431
+ let filterValue;
1432
+
1433
+ switch (this.getOption("filter.position")) {
1434
+ case FILTER_POSITION_INLINE:
1435
+ if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
1436
+ filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
1437
+ } else {
1438
+ return;
1439
+ }
1440
+
1441
+ break;
1442
+ case FILTER_POSITION_POPPER:
1443
+ default:
1444
+ if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
1445
+ filterValue = this[popperFilterElementSymbol].value.toLowerCase();
1446
+ } else {
1447
+ return;
1448
+ }
1449
+ }
1450
+
1451
+ const options = this.getOption("options");
1452
+ for (const [i, option] of Object.entries(options)) {
1453
+ if (option.label.toLowerCase().indexOf(filterValue) === -1) {
1454
+ this.setOption(`options.${i}.filtered`, "true");
1455
+ } else {
1456
+ this.setOption(`options.${i}.filtered`, undefined);
1457
+ }
1458
+ }
1459
+ })
1460
+ .run()
1461
+ .then(() => {
1462
+ new Processing(100, () => {
1463
+ calcAndSetOptionsDimension.call(this);
1464
+ focusFilter.call(this);
1465
+ })
1466
+ .run()
1467
+ .catch((e) => {
1468
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1469
+ });
1470
+ })
1471
+ .catch((e) => {
1472
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1473
+ });
1462
1474
  }
1463
1475
 
1464
1476
  /**
@@ -1466,37 +1478,37 @@ function filterOptions() {
1466
1478
  * @param {Event} event
1467
1479
  */
1468
1480
  function handleFilterKeyboardEvents(event) {
1469
- const shiftKey = event?.["shiftKey"];
1470
-
1471
- switch (event?.["code"]) {
1472
- case "Tab":
1473
- activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1474
- event.preventDefault();
1475
- break;
1476
- case "Escape":
1477
- toggle.call(this);
1478
- event.preventDefault();
1479
- break;
1480
- case "Tab" && shiftKey === true:
1481
- case "ArrowUp":
1482
- activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1483
- event.preventDefault();
1484
- break;
1485
- case "Tab" && !shiftKey:
1486
- case "ArrowDown":
1487
- activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1488
- event.preventDefault();
1489
- break;
1490
- default:
1491
- if (
1492
- this.getOption("features.lazyLoad") === true &&
1493
- this[lazyLoadDoneSymbol] !== true
1494
- ) {
1495
- this.click();
1496
- }
1497
-
1498
- handleFilterKeyEvents.call(this);
1499
- }
1481
+ const shiftKey = event?.["shiftKey"];
1482
+
1483
+ switch (event?.["code"]) {
1484
+ case "Tab":
1485
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1486
+ event.preventDefault();
1487
+ break;
1488
+ case "Escape":
1489
+ toggle.call(this);
1490
+ event.preventDefault();
1491
+ break;
1492
+ case "Tab" && shiftKey === true:
1493
+ case "ArrowUp":
1494
+ activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1495
+ event.preventDefault();
1496
+ break;
1497
+ case "Tab" && !shiftKey:
1498
+ case "ArrowDown":
1499
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1500
+ event.preventDefault();
1501
+ break;
1502
+ default:
1503
+ if (
1504
+ this.getOption("features.lazyLoad") === true &&
1505
+ this[lazyLoadDoneSymbol] !== true
1506
+ ) {
1507
+ this.click();
1508
+ }
1509
+
1510
+ handleFilterKeyEvents.call(this);
1511
+ }
1500
1512
  }
1501
1513
 
1502
1514
  /**
@@ -1510,118 +1522,121 @@ function handleFilterKeyboardEvents(event) {
1510
1522
  * @return {void} This method does not return anything.
1511
1523
  */
1512
1524
  function handleFilterKeyEvents() {
1513
- if (this[keyFilterEventSymbol] instanceof DeadMansSwitch) {
1514
- try {
1515
- this[keyFilterEventSymbol].touch();
1516
- return;
1517
- } catch (e) {
1518
- delete this[keyFilterEventSymbol];
1519
- }
1520
- }
1521
-
1522
- this[keyFilterEventSymbol] = new DeadMansSwitch(200, () => {
1523
- if (this.getOption("filter.mode") !== FILTER_MODE_REMOTE) {
1524
- filterOptions.call(this);
1525
- } else {
1526
- filterFromRemote.call(this).catch((e) => {
1527
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1528
- });
1529
- }
1530
-
1531
- delete this[keyFilterEventSymbol];
1532
- });
1525
+ if (this[keyFilterEventSymbol] instanceof DeadMansSwitch) {
1526
+ try {
1527
+ this[keyFilterEventSymbol].touch();
1528
+ return;
1529
+ } catch (e) {
1530
+ delete this[keyFilterEventSymbol];
1531
+ }
1532
+ }
1533
+
1534
+ this[keyFilterEventSymbol] = new DeadMansSwitch(200, () => {
1535
+ if (getFilterMode.call(this) !== FILTER_MODE_REMOTE) {
1536
+ filterOptions.call(this);
1537
+ } else {
1538
+ filterFromRemote.call(this).catch((e) => {
1539
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1540
+ });
1541
+ }
1542
+
1543
+ delete this[keyFilterEventSymbol];
1544
+ });
1533
1545
  }
1534
1546
 
1535
1547
  /**
1536
1548
  * @private
1537
1549
  */
1538
1550
  function filterFromRemote() {
1539
- if (!(this[inlineFilterElementSymbol] instanceof HTMLElement) && !(this[popperFilterElementSymbol] instanceof HTMLElement)) {
1540
- return;
1541
- }
1542
-
1543
- show.call(this);
1544
-
1545
- const url = this.getOption("url");
1546
- if (!url) {
1547
- addAttributeToken(
1548
- this,
1549
- ATTRIBUTE_ERRORMESSAGE,
1550
- "Missing URL for Remote Filter.",
1551
- );
1552
- return;
1553
- }
1554
-
1555
- let filterValue;
1556
-
1557
- switch (this.getOption("filter.position")) {
1558
- case FILTER_POSITION_INLINE:
1559
- if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
1560
- filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
1561
- }
1562
-
1563
- break;
1564
- case FILTER_POSITION_POPPER:
1565
- default:
1566
- if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
1567
- filterValue = this[popperFilterElementSymbol].value.toLowerCase();
1568
- }
1569
- }
1570
-
1571
- return filterFromRemoteByValue.call(
1572
- this,
1573
- url,
1574
- filterValue
1575
- );
1551
+ if (
1552
+ !(this[inlineFilterElementSymbol] instanceof HTMLElement) &&
1553
+ !(this[popperFilterElementSymbol] instanceof HTMLElement)
1554
+ ) {
1555
+ return;
1556
+ }
1557
+
1558
+ show.call(this);
1559
+
1560
+ const url = this.getOption("url");
1561
+ if (!url) {
1562
+ addAttributeToken(
1563
+ this,
1564
+ ATTRIBUTE_ERRORMESSAGE,
1565
+ "Missing URL for Remote Filter.",
1566
+ );
1567
+ return;
1568
+ }
1569
+
1570
+ let filterValue;
1571
+
1572
+ switch (this.getOption("filter.position")) {
1573
+ case FILTER_POSITION_INLINE:
1574
+ if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
1575
+ filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
1576
+ }
1577
+
1578
+ break;
1579
+ case FILTER_POSITION_POPPER:
1580
+ default:
1581
+ if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
1582
+ filterValue = this[popperFilterElementSymbol].value.toLowerCase();
1583
+ }
1584
+ }
1585
+
1586
+ return filterFromRemoteByValue.call(this, url, filterValue);
1576
1587
  }
1577
1588
 
1578
1589
  function formatURL(url, value) {
1579
- if (value === undefined || value === null || value === "") {
1580
- value = this.getOption("filter.defaultValue");
1581
- if (value === undefined || value === null || value === "") {
1582
- value = disabledRequestMarker.toString();
1583
- }
1584
- }
1585
-
1586
- const formatter = new Formatter({filter: encodeURI(value)});
1587
- const openMarker = this.getOption("filter.marker.open");
1588
- let closeMarker = this.getOption("filter.marker.close");
1589
- if (!closeMarker) {
1590
- closeMarker = openMarker;
1591
- }
1592
-
1593
- if (openMarker && closeMarker) {
1594
- formatter.setMarker(openMarker, closeMarker);
1595
- }
1596
-
1597
- return formatter.format(url);
1590
+ if (value === undefined || value === null || value === "") {
1591
+ value = this.getOption("filter.defaultValue");
1592
+ if (value === undefined || value === null || value === "") {
1593
+ value = disabledRequestMarker.toString();
1594
+ }
1595
+ }
1596
+
1597
+ const formatter = new Formatter({ filter: encodeURI(value) });
1598
+ const openMarker = this.getOption("filter.marker.open");
1599
+ let closeMarker = this.getOption("filter.marker.close");
1600
+ if (!closeMarker) {
1601
+ closeMarker = openMarker;
1602
+ }
1603
+
1604
+ if (openMarker && closeMarker) {
1605
+ formatter.setMarker(openMarker, closeMarker);
1606
+ }
1607
+
1608
+ return formatter.format(url);
1598
1609
  }
1599
1610
 
1600
1611
  /**
1601
1612
  * @private
1613
+ * @param optionUrl
1614
+ * @param value
1615
+ * @returns {Promise<unknown>}
1602
1616
  */
1603
1617
  function filterFromRemoteByValue(optionUrl, value) {
1604
- return new Processing(() => {
1605
-
1606
- let url = formatURL.call(this, optionUrl, value);
1607
- if (url.indexOf(disabledRequestMarker.toString()) !== -1) {
1608
- return;
1609
- }
1610
-
1611
- fetchIt.call(this, url, {
1612
- disableHiding: true,
1613
- })
1614
- .then(() => {
1615
- checkOptionState.call(this);
1616
- show.call(this);
1617
- })
1618
- .catch((e) => {
1619
- throw e;
1620
- });
1621
-
1622
- }).run().catch((e) => {
1623
- throw e;
1624
- });
1618
+ return new Processing(() => {
1619
+ let url = formatURL.call(this, optionUrl, value);
1620
+ if (url.indexOf(disabledRequestMarker.toString()) !== -1) {
1621
+ return;
1622
+ }
1623
+
1624
+ fetchIt
1625
+ .call(this, url, {
1626
+ disableHiding: true,
1627
+ })
1628
+ .then(() => {
1629
+ checkOptionState.call(this);
1630
+ show.call(this);
1631
+ })
1632
+ .catch((e) => {
1633
+ throw e;
1634
+ });
1635
+ })
1636
+ .run()
1637
+ .catch((e) => {
1638
+ throw e;
1639
+ });
1625
1640
  }
1626
1641
 
1627
1642
  /**
@@ -1629,50 +1644,50 @@ function filterFromRemoteByValue(optionUrl, value) {
1629
1644
  * @private
1630
1645
  */
1631
1646
  function handleOptionKeyboardEvents(event) {
1632
- const shiftKey = event?.["shiftKey"];
1633
-
1634
- switch (event?.["code"]) {
1635
- case "Escape":
1636
- toggle.call(this);
1637
- event.preventDefault();
1638
- break;
1639
- case "Enter":
1640
- case "Space":
1641
- const path = event.composedPath();
1642
- const element = path?.[0];
1643
- if (element instanceof HTMLElement) {
1644
- const input = element.getElementsByTagName("input");
1645
- if (!input) {
1646
- return;
1647
- }
1648
- fireEvent(input, "click");
1649
- }
1650
- event.preventDefault();
1651
- break;
1652
-
1653
- case "Tab" && shiftKey === true:
1654
- case "ArrowUp":
1655
- activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1656
- event.preventDefault();
1657
- break;
1658
-
1659
- case "Tab" && !shiftKey:
1660
- case "ArrowLeft":
1661
- case "ArrowRight":
1662
- // handled by tree select
1663
- break;
1664
- case "ArrowDown":
1665
- activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1666
- event.preventDefault();
1667
- break;
1668
- default:
1669
- const p = event.composedPath();
1670
- if (p?.[0] instanceof HTMLInputElement) {
1671
- return;
1672
- }
1673
- focusFilter.call(this);
1674
- break;
1675
- }
1647
+ const shiftKey = event?.["shiftKey"];
1648
+
1649
+ switch (event?.["code"]) {
1650
+ case "Escape":
1651
+ toggle.call(this);
1652
+ event.preventDefault();
1653
+ break;
1654
+ case "Enter":
1655
+ case "Space":
1656
+ const path = event.composedPath();
1657
+ const element = path?.[0];
1658
+ if (element instanceof HTMLElement) {
1659
+ const input = element.getElementsByTagName("input");
1660
+ if (!input) {
1661
+ return;
1662
+ }
1663
+ fireEvent(input, "click");
1664
+ }
1665
+ event.preventDefault();
1666
+ break;
1667
+
1668
+ case "Tab" && shiftKey === true:
1669
+ case "ArrowUp":
1670
+ activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1671
+ event.preventDefault();
1672
+ break;
1673
+
1674
+ case "Tab" && !shiftKey:
1675
+ case "ArrowLeft":
1676
+ case "ArrowRight":
1677
+ // handled by tree select
1678
+ break;
1679
+ case "ArrowDown":
1680
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1681
+ event.preventDefault();
1682
+ break;
1683
+ default:
1684
+ const p = event.composedPath();
1685
+ if (p?.[0] instanceof HTMLInputElement) {
1686
+ return;
1687
+ }
1688
+ focusFilter.call(this);
1689
+ break;
1690
+ }
1676
1691
  }
1677
1692
 
1678
1693
  /**
@@ -1680,33 +1695,33 @@ function handleOptionKeyboardEvents(event) {
1680
1695
  * @return {string}
1681
1696
  */
1682
1697
  function getFilterMode() {
1683
- switch (this.getOption("filter.mode")) {
1684
- case FILTER_MODE_OPTIONS:
1685
- return FILTER_MODE_OPTIONS;
1686
- case FILTER_MODE_REMOTE:
1687
- return FILTER_MODE_REMOTE;
1688
- default:
1689
- return FILTER_MODE_DISABLED;
1690
- }
1698
+ switch (this.getOption("filter.mode")) {
1699
+ case FILTER_MODE_OPTIONS:
1700
+ return FILTER_MODE_OPTIONS;
1701
+ case FILTER_MODE_REMOTE:
1702
+ return FILTER_MODE_REMOTE;
1703
+ default:
1704
+ return FILTER_MODE_DISABLED;
1705
+ }
1691
1706
  }
1692
1707
 
1693
1708
  /**
1694
1709
  * @private
1695
1710
  */
1696
1711
  function blurFilter() {
1697
- if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)) {
1698
- return;
1699
- }
1712
+ if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)) {
1713
+ return;
1714
+ }
1700
1715
 
1701
- if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1702
- return;
1703
- }
1716
+ if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1717
+ return;
1718
+ }
1704
1719
 
1705
- this[popperFilterContainerElementSymbol].classList.remove("active");
1706
- this[popperFilterContainerElementSymbol].blur();
1720
+ this[popperFilterContainerElementSymbol].classList.remove("active");
1721
+ this[popperFilterContainerElementSymbol].blur();
1707
1722
 
1708
- this[inlineFilterElementSymbol].classList.remove("active");
1709
- this[inlineFilterElementSymbol].blur();
1723
+ this[inlineFilterElementSymbol].classList.remove("active");
1724
+ this[inlineFilterElementSymbol].blur();
1710
1725
  }
1711
1726
 
1712
1727
  /**
@@ -1714,29 +1729,29 @@ function blurFilter() {
1714
1729
  * @param focusOptions
1715
1730
  */
1716
1731
  function focusPopperFilter(focusOptions) {
1717
- this[popperFilterContainerElementSymbol].classList.remove("d-none");
1718
- this[popperFilterElementSymbol].classList.add("active");
1719
- this[inlineFilterElementSymbol].classList.remove("active");
1720
- this[inlineFilterElementSymbol].classList.add("d-none");
1721
-
1722
- if (!(this[popperFilterElementSymbol] instanceof HTMLElement)) {
1723
- addAttributeToken(
1724
- this,
1725
- ATTRIBUTE_ERRORMESSAGE,
1726
- "Missing Popper Filter Element.",
1727
- );
1728
- return;
1729
- }
1730
-
1731
- // visibility is set to visible, because focus() does not work on invisible elements
1732
- // and the class definition is assigned later in the processing
1733
- setTimeout(() => {
1734
- if (focusOptions === undefined || focusOptions === null) {
1735
- this[popperFilterElementSymbol].focus();
1736
- } else {
1737
- this[popperFilterElementSymbol].focus(focusOptions);
1738
- }
1739
- }, 100);
1732
+ this[popperFilterContainerElementSymbol].classList.remove("d-none");
1733
+ this[popperFilterElementSymbol].classList.add("active");
1734
+ this[inlineFilterElementSymbol].classList.remove("active");
1735
+ this[inlineFilterElementSymbol].classList.add("d-none");
1736
+
1737
+ if (!(this[popperFilterElementSymbol] instanceof HTMLElement)) {
1738
+ addAttributeToken(
1739
+ this,
1740
+ ATTRIBUTE_ERRORMESSAGE,
1741
+ "Missing Popper Filter Element.",
1742
+ );
1743
+ return;
1744
+ }
1745
+
1746
+ // visibility is set to visible, because focus() does not work on invisible elements
1747
+ // and the class definition is assigned later in the processing
1748
+ setTimeout(() => {
1749
+ if (focusOptions === undefined || focusOptions === null) {
1750
+ this[popperFilterElementSymbol].focus();
1751
+ } else {
1752
+ this[popperFilterElementSymbol].focus(focusOptions);
1753
+ }
1754
+ }, 100);
1740
1755
  }
1741
1756
 
1742
1757
  /**
@@ -1744,44 +1759,44 @@ function focusPopperFilter(focusOptions) {
1744
1759
  * @param focusOptions
1745
1760
  */
1746
1761
  function focusInlineFilter(focusOptions) {
1747
- const options = this.getOption("options");
1748
- if (
1749
- (!isArray(options) || options.length === 0) &&
1750
- this.getOption("filter.mode") !== FILTER_MODE_REMOTE
1751
- ) {
1752
- return;
1753
- }
1754
-
1755
- this[popperFilterContainerElementSymbol].classList.add("d-none");
1756
- this[inlineFilterElementSymbol].classList.add("active");
1757
- this[inlineFilterElementSymbol].classList.remove("d-none");
1758
-
1759
- // visibility is set to visible, because focus() does not work on invisible elements
1760
- // and the class definition is assigned later in the processing
1761
- setTimeout(() => {
1762
- if (focusOptions === undefined || focusOptions === null) {
1763
- this[inlineFilterElementSymbol].focus();
1764
- } else {
1765
- this[inlineFilterElementSymbol].focus(focusOptions);
1766
- }
1767
- }, 100);
1762
+ const options = this.getOption("options");
1763
+ if (
1764
+ (!isArray(options) || options.length === 0) &&
1765
+ getFilterMode.call(this) !== FILTER_MODE_REMOTE
1766
+ ) {
1767
+ return;
1768
+ }
1769
+
1770
+ this[popperFilterContainerElementSymbol].classList.add("d-none");
1771
+ this[inlineFilterElementSymbol].classList.add("active");
1772
+ this[inlineFilterElementSymbol].classList.remove("d-none");
1773
+
1774
+ // visibility is set to visible, because focus() does not work on invisible elements
1775
+ // and the class definition is assigned later in the processing
1776
+ setTimeout(() => {
1777
+ if (focusOptions === undefined || focusOptions === null) {
1778
+ this[inlineFilterElementSymbol].focus();
1779
+ } else {
1780
+ this[inlineFilterElementSymbol].focus(focusOptions);
1781
+ }
1782
+ }, 100);
1768
1783
  }
1769
1784
 
1770
1785
  /**
1771
1786
  * @private
1772
1787
  */
1773
1788
  function focusFilter(focusOptions) {
1774
- if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1775
- this[popperFilterContainerElementSymbol].classList.add("d-none");
1776
- this[inlineFilterElementSymbol].classList.add("d-none");
1777
- return;
1778
- }
1789
+ if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1790
+ this[popperFilterContainerElementSymbol].classList.add("d-none");
1791
+ this[inlineFilterElementSymbol].classList.add("d-none");
1792
+ return;
1793
+ }
1779
1794
 
1780
- if (this.getOption("filter.position") === FILTER_POSITION_INLINE) {
1781
- return focusInlineFilter.call(this, focusOptions);
1782
- }
1795
+ if (this.getOption("filter.position") === FILTER_POSITION_INLINE) {
1796
+ return focusInlineFilter.call(this, focusOptions);
1797
+ }
1783
1798
 
1784
- return focusPopperFilter.call(this, focusOptions);
1799
+ return focusPopperFilter.call(this, focusOptions);
1785
1800
  }
1786
1801
 
1787
1802
  /**
@@ -1791,40 +1806,39 @@ function focusFilter(focusOptions) {
1791
1806
  * @throws {Error} unsupported type
1792
1807
  */
1793
1808
  function gatherState() {
1794
- const type = this.getOption("type");
1795
- if (["radio", "checkbox"].indexOf(type) === -1) {
1796
- throw new Error("unsupported type");
1797
- }
1798
-
1799
- if (!this.shadowRoot) {
1800
- throw new Error("no shadow-root is defined");
1801
- }
1802
-
1803
- const selection = [];
1804
- const elements = this.shadowRoot.querySelectorAll(
1805
- `input[type=${type}]:checked`,
1806
- );
1807
-
1808
- for (const e of elements) {
1809
- selection.push({
1810
- label: getSelectionLabel.call(this, e.value),
1811
- value: e.value,
1812
- });
1813
- }
1814
-
1815
- setSelection
1816
- .call(this, selection)
1817
- .then(() => {
1818
- })
1819
- .catch((e) => {
1820
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1821
- });
1822
-
1823
- if (this.getOption("features.closeOnSelect") === true) {
1824
- toggle.call(this);
1825
- }
1826
-
1827
- return this;
1809
+ const type = this.getOption("type");
1810
+ if (["radio", "checkbox"].indexOf(type) === -1) {
1811
+ throw new Error("unsupported type");
1812
+ }
1813
+
1814
+ if (!this.shadowRoot) {
1815
+ throw new Error("no shadow-root is defined");
1816
+ }
1817
+
1818
+ const selection = [];
1819
+ const elements = this.shadowRoot.querySelectorAll(
1820
+ `input[type=${type}]:checked`,
1821
+ );
1822
+
1823
+ for (const e of elements) {
1824
+ selection.push({
1825
+ label: getSelectionLabel.call(this, e.value),
1826
+ value: e.value,
1827
+ });
1828
+ }
1829
+
1830
+ setSelection
1831
+ .call(this, selection)
1832
+ .then(() => {})
1833
+ .catch((e) => {
1834
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1835
+ });
1836
+
1837
+ if (this.getOption("features.closeOnSelect") === true) {
1838
+ toggle.call(this);
1839
+ }
1840
+
1841
+ return this;
1828
1842
  }
1829
1843
 
1830
1844
  /**
@@ -1833,121 +1847,120 @@ function gatherState() {
1833
1847
  * @throws {Error} unsupported type
1834
1848
  */
1835
1849
  function clearSelection() {
1836
- const type = this.getOption("type");
1837
- if (["radio", "checkbox"].indexOf(type) === -1) {
1838
- throw new Error("unsupported type");
1839
- }
1840
-
1841
- if (!this.shadowRoot) {
1842
- throw new Error("no shadow-root is defined");
1843
- }
1844
-
1845
- setSelection
1846
- .call(this, [])
1847
- .then(() => {
1848
- })
1849
- .catch((e) => {
1850
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1851
- });
1850
+ const type = this.getOption("type");
1851
+ if (["radio", "checkbox"].indexOf(type) === -1) {
1852
+ throw new Error("unsupported type");
1853
+ }
1854
+
1855
+ if (!this.shadowRoot) {
1856
+ throw new Error("no shadow-root is defined");
1857
+ }
1858
+
1859
+ setSelection
1860
+ .call(this, [])
1861
+ .then(() => {})
1862
+ .catch((e) => {
1863
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1864
+ });
1852
1865
  }
1853
1866
 
1854
1867
  /**
1855
1868
  * @private
1856
1869
  */
1857
1870
  function areOptionsAvailableAndInit() {
1858
- // prevent multiple calls
1859
- if (this[areOptionsAvailableAndInitSymbol] === undefined) {
1860
- this[areOptionsAvailableAndInitSymbol] = 0;
1861
- }
1862
-
1863
- if (this[areOptionsAvailableAndInitSymbol] > 0) {
1864
- this[areOptionsAvailableAndInitSymbol]--;
1865
- return true;
1866
- }
1867
-
1868
- this[areOptionsAvailableAndInitSymbol]++;
1869
-
1870
- const options = this.getOption("options");
1871
-
1872
- if (
1873
- options === undefined ||
1874
- options === null ||
1875
- (isArray(options) && options.length === 0)
1876
- ) {
1877
- setStatusOrRemoveBadges.call(this, "empty");
1878
-
1879
- // hide.call(this);
1880
-
1881
- let msg = this.getOption("labels.no-options-available");
1882
-
1883
- if (
1884
- this.getOption("url") !== null &&
1885
- this.getOption("features.lazyLoad") === true &&
1886
- this[lazyLoadDoneSymbol] !== true
1887
- ) {
1888
- msg = this.getOption("labels.click-to-load-options");
1889
- }
1890
-
1891
- this.setOption("messages.control", msg);
1892
- this.setOption("messages.summary", "");
1893
-
1894
- if (this.getOption("features.emptyValueIfNoOptions") === true) {
1895
- this.value = "";
1896
- }
1897
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1898
- return false;
1899
- }
1900
-
1901
- const selections = this.getOption("selection");
1902
- if (
1903
- selections === undefined ||
1904
- selections === null ||
1905
- selections.length === 0
1906
- ) {
1907
- this.setOption(
1908
- "messages.control",
1909
- this.getOption("labels.select-an-option"),
1910
- );
1911
- } else {
1912
- this.setOption("messages.control", "");
1913
- }
1914
-
1915
- this.setOption("messages.summary", setSummaryAndControlText.call(this));
1916
-
1917
- let updated = false;
1918
- let valueCounter = 1;
1919
- for (const option of options) {
1920
- if (option?.visibility === undefined) {
1921
- option.visibility = "visible";
1922
- updated = true;
1923
- }
1924
-
1925
- if (option?.value === undefined && option?.label === undefined) {
1926
- option.value = `${valueCounter++}`;
1927
- option.label = option.value;
1928
- updated = true;
1929
- continue;
1930
- }
1931
-
1932
- if (option?.value === undefined) {
1933
- option.value = option.label;
1934
- updated = true;
1935
- }
1936
-
1937
- if (option?.label === undefined) {
1938
- option.label = option.value;
1939
- updated = true;
1940
- }
1941
- }
1942
-
1943
- if (updated) {
1944
- this.setOption("options", options);
1945
- }
1946
-
1947
- setStatusOrRemoveBadges.call(this);
1948
-
1949
- removeAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1950
- return true;
1871
+ // prevent multiple calls
1872
+ if (this[areOptionsAvailableAndInitSymbol] === undefined) {
1873
+ this[areOptionsAvailableAndInitSymbol] = 0;
1874
+ }
1875
+
1876
+ if (this[areOptionsAvailableAndInitSymbol] > 0) {
1877
+ this[areOptionsAvailableAndInitSymbol]--;
1878
+ return true;
1879
+ }
1880
+
1881
+ this[areOptionsAvailableAndInitSymbol]++;
1882
+
1883
+ const options = this.getOption("options");
1884
+
1885
+ if (
1886
+ options === undefined ||
1887
+ options === null ||
1888
+ (isArray(options) && options.length === 0)
1889
+ ) {
1890
+ setStatusOrRemoveBadges.call(this, "empty");
1891
+
1892
+ // hide.call(this);
1893
+
1894
+ let msg = this.getOption("labels.no-options-available");
1895
+
1896
+ if (
1897
+ this.getOption("url") !== null &&
1898
+ this.getOption("features.lazyLoad") === true &&
1899
+ this[lazyLoadDoneSymbol] !== true
1900
+ ) {
1901
+ msg = this.getOption("labels.click-to-load-options");
1902
+ }
1903
+
1904
+ this.setOption("messages.control", msg);
1905
+ this.setOption("messages.summary", "");
1906
+
1907
+ if (this.getOption("features.emptyValueIfNoOptions") === true) {
1908
+ this.value = "";
1909
+ }
1910
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1911
+ return false;
1912
+ }
1913
+
1914
+ const selections = this.getOption("selection");
1915
+ if (
1916
+ selections === undefined ||
1917
+ selections === null ||
1918
+ selections.length === 0
1919
+ ) {
1920
+ this.setOption(
1921
+ "messages.control",
1922
+ this.getOption("labels.select-an-option"),
1923
+ );
1924
+ } else {
1925
+ this.setOption("messages.control", "");
1926
+ }
1927
+
1928
+ this.setOption("messages.summary", setSummaryAndControlText.call(this));
1929
+
1930
+ let updated = false;
1931
+ let valueCounter = 1;
1932
+ for (const option of options) {
1933
+ if (option?.visibility === undefined) {
1934
+ option.visibility = "visible";
1935
+ updated = true;
1936
+ }
1937
+
1938
+ if (option?.value === undefined && option?.label === undefined) {
1939
+ option.value = `${valueCounter++}`;
1940
+ option.label = option.value;
1941
+ updated = true;
1942
+ continue;
1943
+ }
1944
+
1945
+ if (option?.value === undefined) {
1946
+ option.value = option.label;
1947
+ updated = true;
1948
+ }
1949
+
1950
+ if (option?.label === undefined) {
1951
+ option.label = option.value;
1952
+ updated = true;
1953
+ }
1954
+ }
1955
+
1956
+ if (updated) {
1957
+ this.setOption("options", options);
1958
+ }
1959
+
1960
+ setStatusOrRemoveBadges.call(this);
1961
+
1962
+ removeAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1963
+ return true;
1951
1964
  }
1952
1965
 
1953
1966
  /**
@@ -1955,30 +1968,30 @@ function areOptionsAvailableAndInit() {
1955
1968
  * @throws {Error} no shadow-root is defined
1956
1969
  */
1957
1970
  function checkOptionState() {
1958
- if (!this.shadowRoot) {
1959
- throw new Error("no shadow-root is defined");
1960
- }
1961
-
1962
- const elements = this.shadowRoot.querySelectorAll(
1963
- `[${ATTRIBUTE_ROLE}=option] input`,
1964
- );
1965
-
1966
- let selection = this.getOption("selection");
1967
- if (!isArray(selection)) {
1968
- selection = [];
1969
- }
1970
-
1971
- const checkedValues = selection.map((a) => {
1972
- return a.value;
1973
- });
1974
-
1975
- for (const e of elements) {
1976
- if (checkedValues.indexOf(e.value) !== -1) {
1977
- if (e.checked !== true) e.checked = true;
1978
- } else {
1979
- if (e.checked !== false) e.checked = false;
1980
- }
1981
- }
1971
+ if (!this.shadowRoot) {
1972
+ throw new Error("no shadow-root is defined");
1973
+ }
1974
+
1975
+ const elements = this.shadowRoot.querySelectorAll(
1976
+ `[${ATTRIBUTE_ROLE}=option] input`,
1977
+ );
1978
+
1979
+ let selection = this.getOption("selection");
1980
+ if (!isArray(selection)) {
1981
+ selection = [];
1982
+ }
1983
+
1984
+ const checkedValues = selection.map((a) => {
1985
+ return a.value;
1986
+ });
1987
+
1988
+ for (const e of elements) {
1989
+ if (checkedValues.indexOf(e.value) !== -1) {
1990
+ if (e.checked !== true) e.checked = true;
1991
+ } else {
1992
+ if (e.checked !== false) e.checked = false;
1993
+ }
1994
+ }
1982
1995
  }
1983
1996
 
1984
1997
  /**
@@ -1987,41 +2000,41 @@ function checkOptionState() {
1987
2000
  * @return {Object}
1988
2001
  */
1989
2002
  function convertValueToSelection(value) {
1990
- const selection = [];
1991
-
1992
- if (isString(value)) {
1993
- value = value
1994
- .split(",")
1995
- .map((a) => {
1996
- return a.trim();
1997
- })
1998
- .filter((a) => {
1999
- return a !== "";
2000
- });
2001
- }
2002
-
2003
- if (isString(value) || isInteger(value)) {
2004
- selection.push({
2005
- label: getSelectionLabel.call(this, value),
2006
- value: value,
2007
- });
2008
- } else if (isArray(value)) {
2009
- for (const v of value) {
2010
- selection.push({
2011
- label: getSelectionLabel.call(this, v),
2012
- value: v,
2013
- });
2014
- }
2015
-
2016
- value = value.join(",");
2017
- } else {
2018
- throw new Error("unsupported type");
2019
- }
2020
-
2021
- return {
2022
- selection: selection,
2023
- value: value,
2024
- };
2003
+ const selection = [];
2004
+
2005
+ if (isString(value)) {
2006
+ value = value
2007
+ .split(",")
2008
+ .map((a) => {
2009
+ return a.trim();
2010
+ })
2011
+ .filter((a) => {
2012
+ return a !== "";
2013
+ });
2014
+ }
2015
+
2016
+ if (isString(value) || isInteger(value)) {
2017
+ selection.push({
2018
+ label: getSelectionLabel.call(this, value),
2019
+ value: value,
2020
+ });
2021
+ } else if (isArray(value)) {
2022
+ for (const v of value) {
2023
+ selection.push({
2024
+ label: getSelectionLabel.call(this, v),
2025
+ value: v,
2026
+ });
2027
+ }
2028
+
2029
+ value = value.join(",");
2030
+ } else {
2031
+ throw new Error("unsupported type");
2032
+ }
2033
+
2034
+ return {
2035
+ selection: selection,
2036
+ value: value,
2037
+ };
2025
2038
  }
2026
2039
 
2027
2040
  /**
@@ -2030,22 +2043,22 @@ function convertValueToSelection(value) {
2030
2043
  * @return {string}
2031
2044
  */
2032
2045
  function convertSelectionToValue(selection) {
2033
- const value = [];
2034
-
2035
- if (isArray(selection)) {
2036
- for (const obj of selection) {
2037
- const v = obj?.["value"];
2038
- if (v !== undefined) value.push(v);
2039
- }
2040
- }
2041
-
2042
- if (value.length === 0) {
2043
- return "";
2044
- } else if (value.length === 1) {
2045
- return value.pop();
2046
- }
2047
-
2048
- return value.join(",");
2046
+ const value = [];
2047
+
2048
+ if (isArray(selection)) {
2049
+ for (const obj of selection) {
2050
+ const v = obj?.["value"];
2051
+ if (v !== undefined) value.push(v);
2052
+ }
2053
+ }
2054
+
2055
+ if (value.length === 0) {
2056
+ return "";
2057
+ } else if (value.length === 1) {
2058
+ return value.pop();
2059
+ }
2060
+
2061
+ return value.join(",");
2049
2062
  }
2050
2063
 
2051
2064
  /**
@@ -2055,74 +2068,72 @@ function convertSelectionToValue(selection) {
2055
2068
  * @throws {Error} no shadow-root is defined
2056
2069
  */
2057
2070
  function setSelection(selection) {
2058
-
2059
- if (isString(selection)) {
2060
- const result = convertValueToSelection.call(this, selection);
2061
- selection = result?.selection;
2062
- } else if (selection === undefined) {
2063
- selection = [];
2064
- }
2065
-
2066
- validateArray(selection);
2067
-
2068
- for (let i = 0; i < selection.length; i++) {
2069
-
2070
- var l = getSelectionLabel.call(this, selection[i].value);
2071
- if (l === selection[i].value) {
2072
- l = selection[i].label;
2073
- }
2074
-
2075
- selection[i] = {
2076
- label: l,
2077
- value: selection[i].value,
2078
- };
2079
- }
2080
-
2081
- this.setOption("selection", selection);
2082
- checkOptionState.call(this);
2083
-
2084
- try {
2085
- this?.setFormValue(this.value);
2086
- } catch (e) {
2087
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2088
- }
2089
-
2090
- fireCustomEvent(this, "monster-selected", {
2091
- selection,
2092
- });
2093
-
2094
- return new Processing(() => {
2095
- const CLASSNAME = "selected";
2096
-
2097
- if (!this.shadowRoot) {
2098
- throw new Error("no shadow-root is defined");
2099
- }
2100
-
2101
- const notSelected = this.shadowRoot.querySelectorAll(":not(:checked)");
2102
-
2103
- if (notSelected) {
2104
- notSelected.forEach((node) => {
2105
- const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
2106
- if (parent) {
2107
- parent.classList.remove(CLASSNAME);
2108
- }
2109
- });
2110
- }
2111
-
2112
- const selected = this.shadowRoot.querySelectorAll(":checked");
2113
- if (selected) {
2114
- selected.forEach((node) => {
2115
- const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
2116
- if (parent) {
2117
- parent.classList.add(CLASSNAME);
2118
- }
2119
- });
2120
- }
2121
- })
2122
- .run()
2123
- .catch((e) => {
2124
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2125
- });
2071
+ if (isString(selection)) {
2072
+ const result = convertValueToSelection.call(this, selection);
2073
+ selection = result?.selection;
2074
+ } else if (selection === undefined) {
2075
+ selection = [];
2076
+ }
2077
+
2078
+ validateArray(selection);
2079
+
2080
+ for (let i = 0; i < selection.length; i++) {
2081
+ var l = getSelectionLabel.call(this, selection[i].value);
2082
+ if (l === selection[i].value) {
2083
+ l = selection[i].label;
2084
+ }
2085
+
2086
+ selection[i] = {
2087
+ label: l,
2088
+ value: selection[i].value,
2089
+ };
2090
+ }
2091
+
2092
+ this.setOption("selection", selection);
2093
+ checkOptionState.call(this);
2094
+
2095
+ try {
2096
+ this?.setFormValue(this.value);
2097
+ } catch (e) {
2098
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2099
+ }
2100
+
2101
+ fireCustomEvent(this, "monster-selected", {
2102
+ selection,
2103
+ });
2104
+
2105
+ return new Processing(() => {
2106
+ const CLASSNAME = "selected";
2107
+
2108
+ if (!this.shadowRoot) {
2109
+ throw new Error("no shadow-root is defined");
2110
+ }
2111
+
2112
+ const notSelected = this.shadowRoot.querySelectorAll(":not(:checked)");
2113
+
2114
+ if (notSelected) {
2115
+ notSelected.forEach((node) => {
2116
+ const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
2117
+ if (parent) {
2118
+ parent.classList.remove(CLASSNAME);
2119
+ }
2120
+ });
2121
+ }
2122
+
2123
+ const selected = this.shadowRoot.querySelectorAll(":checked");
2124
+ if (selected) {
2125
+ selected.forEach((node) => {
2126
+ const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
2127
+ if (parent) {
2128
+ parent.classList.add(CLASSNAME);
2129
+ }
2130
+ });
2131
+ }
2132
+ })
2133
+ .run()
2134
+ .catch((e) => {
2135
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2136
+ });
2126
2137
  }
2127
2138
 
2128
2139
  /**
@@ -2133,137 +2144,139 @@ function setSelection(selection) {
2133
2144
  * @throws {TypeError} unsupported response
2134
2145
  */
2135
2146
  function fetchData(url) {
2136
- const self = this;
2137
- if (!url) url = this.getOption("url");
2138
- if (!url) return Promise.resolve();
2139
-
2140
- const fetchOptions = this.getOption("fetch", {});
2141
-
2142
- let delayWatch = false;
2143
-
2144
- // if fetch short time, do not show loading badge, because of flickering
2145
- requestAnimationFrame(() => {
2146
- if (delayWatch === true) return;
2147
- setStatusOrRemoveBadges.call(this, "loading");
2148
- delayWatch = true;
2149
- });
2150
-
2151
- url = formatURL.call(this, url);
2152
-
2153
- self[isLoadingSymbol] = true;
2154
- const global = getGlobal();
2155
- return global
2156
- .fetch(url, fetchOptions)
2157
- .then((response) => {
2158
- self[isLoadingSymbol] = false;
2159
- delayWatch = true;
2160
- const contentType = response.headers.get("content-type");
2161
- if (contentType && contentType.indexOf("application/json") !== -1) {
2162
- return response.text();
2163
- }
2164
-
2165
- throw new TypeError(`unsupported response ${contentType}`);
2166
- })
2167
- .then((text) => {
2168
- try {
2169
- return Promise.resolve(JSON.parse(String(text)));
2170
- } catch (e) {
2171
- throw new TypeError("the result cannot be parsed, check the URL");
2172
- }
2173
- })
2174
- .catch((e) => {
2175
- self[isLoadingSymbol] = false;
2176
- delayWatch = true;
2177
- throw e;
2178
- });
2147
+ const self = this;
2148
+ if (!url) url = this.getOption("url");
2149
+ if (!url) return Promise.resolve();
2150
+
2151
+ const fetchOptions = this.getOption("fetch", {});
2152
+
2153
+ let delayWatch = false;
2154
+
2155
+ // if fetch short time, do not show loading badge, because of flickering
2156
+ requestAnimationFrame(() => {
2157
+ if (delayWatch === true) return;
2158
+ setStatusOrRemoveBadges.call(this, "loading");
2159
+ delayWatch = true;
2160
+ });
2161
+
2162
+ url = formatURL.call(this, url);
2163
+
2164
+ self[isLoadingSymbol] = true;
2165
+ const global = getGlobal();
2166
+ return global
2167
+ .fetch(url, fetchOptions)
2168
+ .then((response) => {
2169
+ self[isLoadingSymbol] = false;
2170
+ delayWatch = true;
2171
+ const contentType = response.headers.get("content-type");
2172
+ if (contentType && contentType.indexOf("application/json") !== -1) {
2173
+ return response.text();
2174
+ }
2175
+
2176
+ throw new TypeError(`unsupported response ${contentType}`);
2177
+ })
2178
+ .then((text) => {
2179
+ try {
2180
+ return Promise.resolve(JSON.parse(String(text)));
2181
+ } catch (e) {
2182
+ throw new TypeError("the result cannot be parsed, check the URL");
2183
+ }
2184
+ })
2185
+ .catch((e) => {
2186
+ self[isLoadingSymbol] = false;
2187
+ delayWatch = true;
2188
+ throw e;
2189
+ });
2179
2190
  }
2180
2191
 
2181
2192
  /**
2182
2193
  * @private
2183
2194
  */
2184
2195
  function hide() {
2185
- this[popperElementSymbol].style.display = "none";
2186
- setStatusOrRemoveBadges.call(this, "closed");
2187
- removeAttributeToken(this[controlElementSymbol], "class", "open");
2196
+ this[popperElementSymbol].style.display = "none";
2197
+ setStatusOrRemoveBadges.call(this, "closed");
2198
+ removeAttributeToken(this[controlElementSymbol], "class", "open");
2188
2199
  }
2189
2200
 
2190
2201
  /**
2191
2202
  * @private
2192
2203
  */
2193
2204
  function show() {
2194
- if (this.getOption("disabled", undefined) === true) {
2195
- return;
2196
- }
2197
-
2198
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
2199
- return;
2200
- }
2201
-
2202
- focusFilter.call(this);
2203
-
2204
- const lazyLoadFlag =
2205
- this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
2206
-
2207
- if (lazyLoadFlag === true) {
2208
- this[lazyLoadDoneSymbol] = true;
2209
- setStatusOrRemoveBadges.call(this, "loading");
2210
-
2211
- new Processing(200, () => {
2212
- this.fetch()
2213
- .then(() => {
2214
- checkOptionState.call(this);
2215
- requestAnimationFrame(() => {
2216
- show.call(this);
2217
- });
2218
- })
2219
- .catch((e) => {
2220
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2221
- setStatusOrRemoveBadges.call(this, "error");
2222
- });
2223
- })
2224
- .run()
2225
- .catch((e) => {
2226
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2227
- setStatusOrRemoveBadges.call(this, "error");
2228
- });
2229
-
2230
- return;
2231
- }
2232
-
2233
- const hasPopperFilterFlag = this.getOption("filter.position") === FILTER_POSITION_POPPER && this.getOption("filter.mode") !== FILTER_MODE_DISABLED;
2234
-
2235
- const options = getOptionElements.call(this);
2236
- if (options.length === 0 && hasPopperFilterFlag === false) {
2237
- return;
2238
- }
2239
-
2240
- this[popperElementSymbol].style.visibility = "hidden";
2241
- this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
2242
- setStatusOrRemoveBadges.call(this, "open");
2243
-
2244
- addAttributeToken(this[controlElementSymbol], "class", "open");
2245
-
2246
- new Processing(() => {
2247
- calcAndSetOptionsDimension.call(this);
2248
- focusFilter.call(this);
2249
- this[popperElementSymbol].style.removeProperty("visibility");
2250
- updatePopper.call(this);
2251
- })
2252
- .run()
2253
- .catch((e) => {
2254
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2255
- });
2205
+ if (this.getOption("disabled", undefined) === true) {
2206
+ return;
2207
+ }
2208
+
2209
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
2210
+ return;
2211
+ }
2212
+
2213
+ focusFilter.call(this);
2214
+
2215
+ const lazyLoadFlag =
2216
+ this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
2217
+
2218
+ if (lazyLoadFlag === true) {
2219
+ this[lazyLoadDoneSymbol] = true;
2220
+ setStatusOrRemoveBadges.call(this, "loading");
2221
+
2222
+ new Processing(200, () => {
2223
+ this.fetch()
2224
+ .then(() => {
2225
+ checkOptionState.call(this);
2226
+ requestAnimationFrame(() => {
2227
+ show.call(this);
2228
+ });
2229
+ })
2230
+ .catch((e) => {
2231
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2232
+ setStatusOrRemoveBadges.call(this, "error");
2233
+ });
2234
+ })
2235
+ .run()
2236
+ .catch((e) => {
2237
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2238
+ setStatusOrRemoveBadges.call(this, "error");
2239
+ });
2240
+
2241
+ return;
2242
+ }
2243
+
2244
+ const hasPopperFilterFlag =
2245
+ this.getOption("filter.position") === FILTER_POSITION_POPPER &&
2246
+ getFilterMode.call(this) !== FILTER_MODE_DISABLED;
2247
+
2248
+ const options = getOptionElements.call(this);
2249
+ if (options.length === 0 && hasPopperFilterFlag === false) {
2250
+ return;
2251
+ }
2252
+
2253
+ this[popperElementSymbol].style.visibility = "hidden";
2254
+ this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
2255
+ setStatusOrRemoveBadges.call(this, "open");
2256
+
2257
+ addAttributeToken(this[controlElementSymbol], "class", "open");
2258
+
2259
+ new Processing(() => {
2260
+ calcAndSetOptionsDimension.call(this);
2261
+ focusFilter.call(this);
2262
+ this[popperElementSymbol].style.removeProperty("visibility");
2263
+ updatePopper.call(this);
2264
+ })
2265
+ .run()
2266
+ .catch((e) => {
2267
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2268
+ });
2256
2269
  }
2257
2270
 
2258
2271
  /**
2259
2272
  * @private
2260
2273
  */
2261
2274
  function toggle() {
2262
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
2263
- hide.call(this);
2264
- } else {
2265
- show.call(this);
2266
- }
2275
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
2276
+ hide.call(this);
2277
+ } else {
2278
+ show.call(this);
2279
+ }
2267
2280
  }
2268
2281
 
2269
2282
  /**
@@ -2272,188 +2285,188 @@ function toggle() {
2272
2285
  * @fires monster-selection-cleared
2273
2286
  */
2274
2287
  function initEventHandler() {
2275
- const self = this;
2276
-
2277
- /**
2278
- * @param {Event} event
2279
- */
2280
- self[clearOptionEventHandler] = (event) => {
2281
- const element = findTargetElementFromEvent(
2282
- event,
2283
- ATTRIBUTE_ROLE,
2284
- "remove-badge",
2285
- );
2286
-
2287
- if (element instanceof HTMLElement) {
2288
- const badge = findClosestByAttribute(element, ATTRIBUTE_ROLE, "badge");
2289
- if (badge instanceof HTMLElement) {
2290
- const value = badge.getAttribute(`${ATTRIBUTE_PREFIX}value`);
2291
-
2292
- let selection = self.getOption("selection");
2293
- selection = selection.filter((b) => {
2294
- return value !== b.value;
2295
- });
2296
-
2297
- setSelection
2298
- .call(self, selection)
2299
- .then(() => {
2300
- fireCustomEvent(self, "monster-selection-removed", {
2301
- value,
2302
- });
2303
- })
2304
- .catch((e) => {
2305
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message);
2306
- });
2307
- }
2308
- }
2309
- };
2310
-
2311
- /**
2312
- * @param {Event} event
2313
- */
2314
- self[closeEventHandler] = (event) => {
2315
- const path = event.composedPath();
2316
-
2317
- for (const [, element] of Object.entries(path)) {
2318
- if (element === self) {
2319
- return;
2320
- }
2321
- }
2322
- hide.call(self);
2323
- };
2324
-
2325
- /**
2326
- * @param {Event} event
2327
- */
2328
- self[inputEventHandler] = (event) => {
2329
- const path = event.composedPath();
2330
- const element = path?.[0];
2331
-
2332
- if (element instanceof HTMLElement) {
2333
- if (
2334
- element.hasAttribute(ATTRIBUTE_ROLE) &&
2335
- element.getAttribute(ATTRIBUTE_ROLE) === "option-control"
2336
- ) {
2337
- fireCustomEvent(self, "monster-change", {
2338
- type: event.type,
2339
- value: element.value,
2340
- checked: element.checked,
2341
- });
2342
- } else if (
2343
- element.hasAttribute(ATTRIBUTE_ROLE) &&
2344
- element.getAttribute(ATTRIBUTE_ROLE) === "filter"
2345
- ) {
2346
- }
2347
- }
2348
- };
2349
-
2350
- /**
2351
- * @param {Event} event
2352
- */
2353
- self[changeEventHandler] = (event) => {
2354
- gatherState.call(self);
2355
- fireCustomEvent(self, "monster-changed", event?.detail);
2356
- };
2357
-
2358
- self[keyEventHandler] = (event) => {
2359
- const path = event.composedPath();
2360
- const element = path.shift();
2361
-
2362
- let role;
2363
-
2364
- if (element instanceof HTMLElement) {
2365
- if (element.hasAttribute(ATTRIBUTE_ROLE)) {
2366
- role = element.getAttribute(ATTRIBUTE_ROLE);
2367
- } else if (element === this) {
2368
- show.call(this);
2369
- // focusFilter.call(self);
2370
- } else {
2371
- const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
2372
- if (e instanceof HTMLElement && e.hasAttribute(ATTRIBUTE_ROLE)) {
2373
- role = e.getAttribute(ATTRIBUTE_ROLE);
2374
- }
2375
- }
2376
- } else {
2377
- return;
2378
- }
2379
-
2380
- switch (role) {
2381
- case "filter":
2382
- handleFilterKeyboardEvents.call(self, event);
2383
- break;
2384
- case "option-label":
2385
- case "option-control":
2386
- case "option":
2387
- handleOptionKeyboardEvents.call(self, event);
2388
- break;
2389
- case "control":
2390
- case "toggle":
2391
- handleToggleKeyboardEvents.call(self, event);
2392
- break;
2393
- }
2394
- };
2395
-
2396
- const types = self.getOption("toggleEventType", ["click"]);
2397
-
2398
- for (const [, type] of Object.entries(types)) {
2399
- self[controlElementSymbol]
2400
- .querySelector(`[${ATTRIBUTE_ROLE}="container"]`)
2401
- .addEventListener(type, function (event) {
2402
- const element = findTargetElementFromEvent(
2403
- event,
2404
- ATTRIBUTE_ROLE,
2405
- "remove-badge",
2406
- );
2407
- if (element instanceof HTMLElement) {
2408
- return;
2409
- }
2410
-
2411
- toggle.call(self);
2412
- });
2413
-
2414
- self[controlElementSymbol]
2415
- .querySelector(`[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`)
2416
- .addEventListener(type, function (event) {
2417
- if (self.getOption("disabled", undefined) === true) {
2418
- return;
2419
- }
2420
-
2421
- const path = event.composedPath();
2422
- const element = path?.[0];
2423
- if (element instanceof HTMLElement) {
2424
- const control = element.closest(
2425
- `[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`,
2426
- );
2427
- if (control instanceof HTMLElement) {
2428
- if (control.classList.contains("clear")) {
2429
- clearSelection.call(self);
2430
-
2431
- fireCustomEvent(self, "monster-selection-cleared", {});
2432
- } else {
2433
- const element = findTargetElementFromEvent(
2434
- event,
2435
- ATTRIBUTE_ROLE,
2436
- "remove-badge",
2437
- );
2438
- if (element instanceof HTMLElement) {
2439
- return;
2440
- }
2441
-
2442
- toggle.call(self);
2443
- }
2444
- }
2445
- }
2446
- });
2447
-
2448
- // badge, selection
2449
- self.addEventListener(type, self[clearOptionEventHandler]);
2450
- }
2451
-
2452
- self.addEventListener("monster-change", self[changeEventHandler]);
2453
- self.addEventListener("input", self[inputEventHandler]);
2454
- self.addEventListener("keydown", self[keyEventHandler]);
2455
-
2456
- return self;
2288
+ const self = this;
2289
+
2290
+ /**
2291
+ * @param {Event} event
2292
+ */
2293
+ self[clearOptionEventHandler] = (event) => {
2294
+ const element = findTargetElementFromEvent(
2295
+ event,
2296
+ ATTRIBUTE_ROLE,
2297
+ "remove-badge",
2298
+ );
2299
+
2300
+ if (element instanceof HTMLElement) {
2301
+ const badge = findClosestByAttribute(element, ATTRIBUTE_ROLE, "badge");
2302
+ if (badge instanceof HTMLElement) {
2303
+ const value = badge.getAttribute(`${ATTRIBUTE_PREFIX}value`);
2304
+
2305
+ let selection = self.getOption("selection");
2306
+ selection = selection.filter((b) => {
2307
+ return value !== b.value;
2308
+ });
2309
+
2310
+ setSelection
2311
+ .call(self, selection)
2312
+ .then(() => {
2313
+ fireCustomEvent(self, "monster-selection-removed", {
2314
+ value,
2315
+ });
2316
+ })
2317
+ .catch((e) => {
2318
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message);
2319
+ });
2320
+ }
2321
+ }
2322
+ };
2323
+
2324
+ /**
2325
+ * @param {Event} event
2326
+ */
2327
+ self[closeEventHandler] = (event) => {
2328
+ const path = event.composedPath();
2329
+
2330
+ for (const [, element] of Object.entries(path)) {
2331
+ if (element === self) {
2332
+ return;
2333
+ }
2334
+ }
2335
+ hide.call(self);
2336
+ };
2337
+
2338
+ /**
2339
+ * @param {Event} event
2340
+ */
2341
+ self[inputEventHandler] = (event) => {
2342
+ const path = event.composedPath();
2343
+ const element = path?.[0];
2344
+
2345
+ if (element instanceof HTMLElement) {
2346
+ if (
2347
+ element.hasAttribute(ATTRIBUTE_ROLE) &&
2348
+ element.getAttribute(ATTRIBUTE_ROLE) === "option-control"
2349
+ ) {
2350
+ fireCustomEvent(self, "monster-change", {
2351
+ type: event.type,
2352
+ value: element.value,
2353
+ checked: element.checked,
2354
+ });
2355
+ } else if (
2356
+ element.hasAttribute(ATTRIBUTE_ROLE) &&
2357
+ element.getAttribute(ATTRIBUTE_ROLE) === "filter"
2358
+ ) {
2359
+ }
2360
+ }
2361
+ };
2362
+
2363
+ /**
2364
+ * @param {Event} event
2365
+ */
2366
+ self[changeEventHandler] = (event) => {
2367
+ gatherState.call(self);
2368
+ fireCustomEvent(self, "monster-changed", event?.detail);
2369
+ };
2370
+
2371
+ self[keyEventHandler] = (event) => {
2372
+ const path = event.composedPath();
2373
+ const element = path.shift();
2374
+
2375
+ let role;
2376
+
2377
+ if (element instanceof HTMLElement) {
2378
+ if (element.hasAttribute(ATTRIBUTE_ROLE)) {
2379
+ role = element.getAttribute(ATTRIBUTE_ROLE);
2380
+ } else if (element === this) {
2381
+ show.call(this);
2382
+ // focusFilter.call(self);
2383
+ } else {
2384
+ const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
2385
+ if (e instanceof HTMLElement && e.hasAttribute(ATTRIBUTE_ROLE)) {
2386
+ role = e.getAttribute(ATTRIBUTE_ROLE);
2387
+ }
2388
+ }
2389
+ } else {
2390
+ return;
2391
+ }
2392
+
2393
+ switch (role) {
2394
+ case "filter":
2395
+ handleFilterKeyboardEvents.call(self, event);
2396
+ break;
2397
+ case "option-label":
2398
+ case "option-control":
2399
+ case "option":
2400
+ handleOptionKeyboardEvents.call(self, event);
2401
+ break;
2402
+ case "control":
2403
+ case "toggle":
2404
+ handleToggleKeyboardEvents.call(self, event);
2405
+ break;
2406
+ }
2407
+ };
2408
+
2409
+ const types = self.getOption("toggleEventType", ["click"]);
2410
+
2411
+ for (const [, type] of Object.entries(types)) {
2412
+ self[controlElementSymbol]
2413
+ .querySelector(`[${ATTRIBUTE_ROLE}="container"]`)
2414
+ .addEventListener(type, function (event) {
2415
+ const element = findTargetElementFromEvent(
2416
+ event,
2417
+ ATTRIBUTE_ROLE,
2418
+ "remove-badge",
2419
+ );
2420
+ if (element instanceof HTMLElement) {
2421
+ return;
2422
+ }
2423
+
2424
+ toggle.call(self);
2425
+ });
2426
+
2427
+ self[controlElementSymbol]
2428
+ .querySelector(`[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`)
2429
+ .addEventListener(type, function (event) {
2430
+ if (self.getOption("disabled", undefined) === true) {
2431
+ return;
2432
+ }
2433
+
2434
+ const path = event.composedPath();
2435
+ const element = path?.[0];
2436
+ if (element instanceof HTMLElement) {
2437
+ const control = element.closest(
2438
+ `[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`,
2439
+ );
2440
+ if (control instanceof HTMLElement) {
2441
+ if (control.classList.contains("clear")) {
2442
+ clearSelection.call(self);
2443
+
2444
+ fireCustomEvent(self, "monster-selection-cleared", {});
2445
+ } else {
2446
+ const element = findTargetElementFromEvent(
2447
+ event,
2448
+ ATTRIBUTE_ROLE,
2449
+ "remove-badge",
2450
+ );
2451
+ if (element instanceof HTMLElement) {
2452
+ return;
2453
+ }
2454
+
2455
+ toggle.call(self);
2456
+ }
2457
+ }
2458
+ }
2459
+ });
2460
+
2461
+ // badge, selection
2462
+ self.addEventListener(type, self[clearOptionEventHandler]);
2463
+ }
2464
+
2465
+ self.addEventListener("monster-change", self[changeEventHandler]);
2466
+ self.addEventListener("input", self[inputEventHandler]);
2467
+ self.addEventListener("keydown", self[keyEventHandler]);
2468
+
2469
+ return self;
2457
2470
  }
2458
2471
 
2459
2472
  /**
@@ -2461,70 +2474,70 @@ function initEventHandler() {
2461
2474
  * @return {Select}
2462
2475
  */
2463
2476
  function setStatusOrRemoveBadges(suggestion) {
2464
- requestAnimationFrame(() => {
2465
- const selection = this.getOption("selection");
2466
-
2467
- const clearAllFlag =
2468
- isArray(selection) &&
2469
- selection.length > 0 &&
2470
- this.getOption("features.clearAll") === true;
2471
-
2472
- const current = this.getOption("classes.statusOrRemoveBadge");
2473
-
2474
- if (suggestion === "error") {
2475
- if (current !== "error") {
2476
- this.setOption("classes.statusOrRemoveBadge", "error");
2477
- }
2478
- return;
2479
- }
2480
-
2481
- if (this[isLoadingSymbol] === true) {
2482
- if (current !== "loading") {
2483
- this.setOption("classes.statusOrRemoveBadge", "loading");
2484
- }
2485
- return;
2486
- }
2487
-
2488
- if (suggestion === "loading") {
2489
- if (current !== "loading") {
2490
- this.setOption("classes.statusOrRemoveBadge", "loading");
2491
- }
2492
- return;
2493
- }
2494
-
2495
- if (clearAllFlag) {
2496
- if (current !== "clear") {
2497
- this.setOption("classes.statusOrRemoveBadge", "clear");
2498
- }
2499
- return;
2500
- }
2501
-
2502
- if (this[controlElementSymbol].classList.contains("open")) {
2503
- if (current !== "open") {
2504
- this.setOption("classes.statusOrRemoveBadge", "open");
2505
- }
2506
- return;
2507
- }
2508
-
2509
- const options = this.getOption("options");
2510
- if (
2511
- options === undefined ||
2512
- options === null ||
2513
- (isArray(options) && options.length === 0)
2514
- ) {
2515
- if (current !== "empty") {
2516
- this.setOption("classes.statusOrRemoveBadge", "empty");
2517
- }
2518
- return;
2519
- }
2520
-
2521
- if (suggestion) {
2522
- if (current !== suggestion) {
2523
- this.setOption("classes.statusOrRemoveBadge", suggestion);
2524
- }
2525
- return;
2526
- }
2527
- });
2477
+ requestAnimationFrame(() => {
2478
+ const selection = this.getOption("selection");
2479
+
2480
+ const clearAllFlag =
2481
+ isArray(selection) &&
2482
+ selection.length > 0 &&
2483
+ this.getOption("features.clearAll") === true;
2484
+
2485
+ const current = this.getOption("classes.statusOrRemoveBadge");
2486
+
2487
+ if (suggestion === "error") {
2488
+ if (current !== "error") {
2489
+ this.setOption("classes.statusOrRemoveBadge", "error");
2490
+ }
2491
+ return;
2492
+ }
2493
+
2494
+ if (this[isLoadingSymbol] === true) {
2495
+ if (current !== "loading") {
2496
+ this.setOption("classes.statusOrRemoveBadge", "loading");
2497
+ }
2498
+ return;
2499
+ }
2500
+
2501
+ if (suggestion === "loading") {
2502
+ if (current !== "loading") {
2503
+ this.setOption("classes.statusOrRemoveBadge", "loading");
2504
+ }
2505
+ return;
2506
+ }
2507
+
2508
+ if (clearAllFlag) {
2509
+ if (current !== "clear") {
2510
+ this.setOption("classes.statusOrRemoveBadge", "clear");
2511
+ }
2512
+ return;
2513
+ }
2514
+
2515
+ if (this[controlElementSymbol].classList.contains("open")) {
2516
+ if (current !== "open") {
2517
+ this.setOption("classes.statusOrRemoveBadge", "open");
2518
+ }
2519
+ return;
2520
+ }
2521
+
2522
+ const options = this.getOption("options");
2523
+ if (
2524
+ options === undefined ||
2525
+ options === null ||
2526
+ (isArray(options) && options.length === 0)
2527
+ ) {
2528
+ if (current !== "empty") {
2529
+ this.setOption("classes.statusOrRemoveBadge", "empty");
2530
+ }
2531
+ return;
2532
+ }
2533
+
2534
+ if (suggestion) {
2535
+ if (current !== suggestion) {
2536
+ this.setOption("classes.statusOrRemoveBadge", suggestion);
2537
+ }
2538
+ return;
2539
+ }
2540
+ });
2528
2541
  }
2529
2542
 
2530
2543
  /**
@@ -2533,68 +2546,68 @@ function setStatusOrRemoveBadges(suggestion) {
2533
2546
  * @throws {Error} no shadow-root is defined
2534
2547
  */
2535
2548
  function initControlReferences() {
2536
- if (!this.shadowRoot) {
2537
- throw new Error("no shadow-root is defined");
2538
- }
2539
-
2540
- this[controlElementSymbol] = this.shadowRoot.querySelector(
2541
- `[${ATTRIBUTE_ROLE}=control]`,
2542
- );
2543
- this[selectionElementSymbol] = this.shadowRoot.querySelector(
2544
- `[${ATTRIBUTE_ROLE}=selection]`,
2545
- );
2546
- this[containerElementSymbol] = this.shadowRoot.querySelector(
2547
- `[${ATTRIBUTE_ROLE}=container]`,
2548
- );
2549
- this[popperElementSymbol] = this.shadowRoot.querySelector(
2550
- `[${ATTRIBUTE_ROLE}=popper]`,
2551
- );
2552
- this[inlineFilterElementSymbol] = this.shadowRoot.querySelector(
2553
- `[${ATTRIBUTE_ROLE}=filter][name="inline-filter"]`,
2554
- );
2555
- this[popperFilterElementSymbol] = this.shadowRoot.querySelector(
2556
- `[${ATTRIBUTE_ROLE}=filter][name="popper-filter"]`,
2557
- );
2558
- this[popperFilterContainerElementSymbol] =
2559
- this[popperFilterElementSymbol].parentElement;
2560
- this[optionsElementSymbol] = this.shadowRoot.querySelector(
2561
- `[${ATTRIBUTE_ROLE}=options]`,
2562
- );
2563
- this[noOptionsAvailableElementSymbol] = this.shadowRoot.querySelector(
2564
- `[${ATTRIBUTE_ROLE}="no-options"]`,
2565
- );
2566
- this[statusOrRemoveBadgesElementSymbol] = this.shadowRoot.querySelector(
2567
- `[${ATTRIBUTE_ROLE}=status-or-remove-badges]`,
2568
- );
2549
+ if (!this.shadowRoot) {
2550
+ throw new Error("no shadow-root is defined");
2551
+ }
2552
+
2553
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
2554
+ `[${ATTRIBUTE_ROLE}=control]`,
2555
+ );
2556
+ this[selectionElementSymbol] = this.shadowRoot.querySelector(
2557
+ `[${ATTRIBUTE_ROLE}=selection]`,
2558
+ );
2559
+ this[containerElementSymbol] = this.shadowRoot.querySelector(
2560
+ `[${ATTRIBUTE_ROLE}=container]`,
2561
+ );
2562
+ this[popperElementSymbol] = this.shadowRoot.querySelector(
2563
+ `[${ATTRIBUTE_ROLE}=popper]`,
2564
+ );
2565
+ this[inlineFilterElementSymbol] = this.shadowRoot.querySelector(
2566
+ `[${ATTRIBUTE_ROLE}=filter][name="inline-filter"]`,
2567
+ );
2568
+ this[popperFilterElementSymbol] = this.shadowRoot.querySelector(
2569
+ `[${ATTRIBUTE_ROLE}=filter][name="popper-filter"]`,
2570
+ );
2571
+ this[popperFilterContainerElementSymbol] =
2572
+ this[popperFilterElementSymbol].parentElement;
2573
+ this[optionsElementSymbol] = this.shadowRoot.querySelector(
2574
+ `[${ATTRIBUTE_ROLE}=options]`,
2575
+ );
2576
+ this[noOptionsAvailableElementSymbol] = this.shadowRoot.querySelector(
2577
+ `[${ATTRIBUTE_ROLE}="no-options"]`,
2578
+ );
2579
+ this[statusOrRemoveBadgesElementSymbol] = this.shadowRoot.querySelector(
2580
+ `[${ATTRIBUTE_ROLE}=status-or-remove-badges]`,
2581
+ );
2569
2582
  }
2570
2583
 
2571
2584
  /**
2572
2585
  * @private
2573
2586
  */
2574
2587
  function updatePopper() {
2575
- if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
2576
- return;
2577
- }
2578
-
2579
- if (this.getOption("disabled", false) === true) {
2580
- return;
2581
- }
2582
-
2583
- new Processing(() => {
2584
- calcAndSetOptionsDimension.call(this);
2585
- positionPopper.call(
2586
- this,
2587
- this[controlElementSymbol],
2588
- this[popperElementSymbol],
2589
- this.getOption("popper", {}),
2590
- );
2591
- })
2592
- .run()
2593
- .catch((e) => {
2594
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2595
- });
2596
-
2597
- return this;
2588
+ if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
2589
+ return;
2590
+ }
2591
+
2592
+ if (this.getOption("disabled", false) === true) {
2593
+ return;
2594
+ }
2595
+
2596
+ new Processing(() => {
2597
+ calcAndSetOptionsDimension.call(this);
2598
+ positionPopper.call(
2599
+ this,
2600
+ this[controlElementSymbol],
2601
+ this[popperElementSymbol],
2602
+ this.getOption("popper", {}),
2603
+ );
2604
+ })
2605
+ .run()
2606
+ .catch((e) => {
2607
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
2608
+ });
2609
+
2610
+ return this;
2598
2611
  }
2599
2612
 
2600
2613
  /**
@@ -2602,8 +2615,8 @@ function updatePopper() {
2602
2615
  * @return {string}
2603
2616
  */
2604
2617
  function getTemplate() {
2605
- // language=HTML
2606
- return `
2618
+ // language=HTML
2619
+ return `
2607
2620
  <template id="options">
2608
2621
  <div data-monster-role="option" tabindex="-1"
2609
2622
  data-monster-attributes="