@schukai/monster 3.80.4 → 3.80.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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="