@schukai/monster 4.136.5 → 4.136.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -17,11 +17,13 @@
17
17
  - **popper:** guard show/hide/update flows against disconnected hosts and missing internal elements
18
18
  - **message-state-button:** distinguish overlay, prose, and wide message layouts for smart popper sizing and overflow ([#401](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/401))
19
19
  - **popper:** support kebab-case camelCase option attributes such as `data-monster-option-popper-content-overflow` ([#401](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/401))
20
+ - **popper/select:** let nested `monster-select` poppers escape parent popper content wrappers without shrinking normal parent content sizing ([#416](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/work_items/416))
20
21
 
21
22
  ### Changes
22
23
 
23
24
  - document lifecycle ownership rules for Updater-driven and stateful custom element implementations
24
25
  - document smart message popper layout behavior for forms and feedback flows ([#401](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/401))
26
+ - document and add an issue repro for nested `monster-select` overflow behavior in `monster-popper-button` ([#416](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/work_items/416))
25
27
 
26
28
 
27
29
 
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.136.5"}
1
+ {"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.136.7"}
@@ -71,6 +71,7 @@ import {
71
71
  openPositionedPopper,
72
72
  positionPopper,
73
73
  resolveClippingBoundaryElement,
74
+ resolveParentPopperContentBoundary,
74
75
  } from "./util/floating-ui.mjs";
75
76
  import { Pathfinder } from "../../data/pathfinder.mjs";
76
77
  import { TokenList } from "../../types/tokenlist.mjs";
@@ -261,21 +262,17 @@ const remoteInfoElementSymbol = Symbol("remoteInfoElement");
261
262
  const areOptionsAvailableAndInitSymbol = Symbol("@@areOptionsAvailableAndInit");
262
263
 
263
264
  /**
265
+ * Internal sentinel used to suppress a remote request after URL formatting.
266
+ *
267
+ * This is currently inserted only when `filter.defaultValue` resolves to
268
+ * `undefined` or `null`. An empty string is treated as a real filter value and
269
+ * therefore still produces a request.
270
+ *
264
271
  * @private
265
272
  * @type {symbol}
266
273
  */
267
274
  const disabledRequestMarker = Symbol("@@disabledRequestMarker");
268
275
 
269
- /**
270
- * @private
271
- * @type {symbol}
272
- */
273
- const runLookupOnceSymbol = Symbol("runLookupOnce");
274
-
275
- /**
276
- * @private
277
- * @type {symbol}
278
- */
279
276
  const cleanupOptionsListSymbol = Symbol("cleanupOptionsList");
280
277
  const optionsVersionSymbol = Symbol("optionsVersion");
281
278
  const pendingSelectionSymbol = Symbol("pendingSelection");
@@ -300,16 +297,6 @@ const debounceOptionsMutationObserverSymbol = Symbol(
300
297
  */
301
298
  const currentPageSymbol = Symbol("currentPage");
302
299
 
303
- /**
304
- * @private
305
- * @type {symbol}
306
- */
307
- const remoteFilterFirstOpendSymbol = Symbol("remoteFilterFirstOpend");
308
-
309
- /**
310
- * @private
311
- * @type {symbol}
312
- */
313
300
  const lookupCacheSymbol = Symbol("lookupCache");
314
301
 
315
302
  /**
@@ -317,6 +304,7 @@ const lookupCacheSymbol = Symbol("lookupCache");
317
304
  * @type {symbol}
318
305
  */
319
306
  const lookupInProgressSymbol = Symbol("lookupInProgress");
307
+ const unresolvedSelectionValuesSymbol = Symbol("unresolvedSelectionValues");
320
308
  const fetchRequestVersionSymbol = Symbol("fetchRequestVersion");
321
309
 
322
310
  /**
@@ -398,6 +386,7 @@ class Select extends CustomControl {
398
386
  this[currentPageSymbol] = 1;
399
387
  this[lookupCacheSymbol] = new Map();
400
388
  this[lookupInProgressSymbol] = new Map();
389
+ this[unresolvedSelectionValuesSymbol] = new Set();
401
390
  this[optionsMapSymbol] = new Map();
402
391
  this[closeOnSelectAutoSymbol] = true;
403
392
  initOptionObserver.call(this);
@@ -480,8 +469,8 @@ class Select extends CustomControl {
480
469
  * @property {string} name - Name of the hidden form field for form submission.
481
470
  * @property {string|null} url - URL to dynamically fetch options via HTTP when opening or filtering.
482
471
  * @property {number|null} total - Total number of available options, useful for pagination with remote data.
483
- * @property {Object} lookup - Configuration for fetching initially selected values.
484
- * @property {string|null} lookup.url - URL template with a `${filter}` placeholder to look up selected entries on initialization. Used when `url` is set and either `features.lazyLoad` is active or `filter.mode` is `"remote"`.
472
+ * @property {Object} lookup - Configuration for hydrating already selected values.
473
+ * @property {string|null} lookup.url - URL template with a `${filter}` placeholder to look up selected entries. Prefer a stable value-based lookup endpoint. This is used for initial hydration and for resolving labels of externally assigned selections that are not yet present in the local option map.
485
474
  * @property {boolean} lookup.grouping - If `true`, all selected values are fetched in a single request; otherwise, a separate request is sent for each value.
486
475
  * @property {Object} fetch - Configuration for HTTP requests via `fetch`.
487
476
  * @property {string} fetch.redirect - Fetch redirect mode (e.g., "error", "follow").
@@ -490,7 +479,7 @@ class Select extends CustomControl {
490
479
  * @property {string} fetch.credentials - Credentials policy for fetch (e.g., "include", "same-origin").
491
480
  * @property {Object.<string, string>} fetch.headers - HTTP headers to be sent with every request.
492
481
  * @property {Object} labels - Text labels for various states and UI elements.
493
- * @property {string} labels.cannot-be-loaded - Message displayed when options cannot be loaded.
482
+ * @property {string} labels.cannot-be-loaded - Message displayed when options cannot be loaded. Unresolved selected values keep their raw key instead of replacing it with this label.
494
483
  * @property {string} labels.no-options-available - Message displayed when no static options are provided.
495
484
  * @property {string} labels.click-to-load-options - Prompt to load options when `features.lazyLoad` is enabled.
496
485
  * @property {string} labels.select-an-option - Placeholder text when no selection has been made.
@@ -513,10 +502,10 @@ class Select extends CustomControl {
513
502
  * @property {Object} placeholder - Placeholder texts for input fields.
514
503
  * @property {string} placeholder.filter - Placeholder text for the filter input field.
515
504
  * @property {Object} filter - Configuration for the filtering functionality.
516
- * @property {string|null} filter.defaultValue - Default filter value for remote requests. An empty string will prevent the initial request.
505
+ * @property {string|null} filter.defaultValue - Default filter value for remote requests. In the current implementation only `undefined` or `null` suppress the request by inserting an internal disabled marker. An empty string `""` is still formatted into the URL and therefore does not prevent the request.
517
506
  * @property {"options"|"remote"|"disabled"} filter.mode - Filter mode: `"options"` (client-side), `"remote"` (server-side, `lazyLoad` is ignored), or `"disabled"`.
518
507
  * @property {"inline"|"popper"} filter.position - Position of the filter input: `"inline"` (inside the control) or `"popper"` (inside the dropdown).
519
- * @property {string|null} filter.defaultOptionsUrl - URL to load an initial list of options when `filter.mode` is `"remote"` and no filter value has been entered.
508
+ * @property {string|null} filter.defaultOptionsUrl - URL to load options when `filter.mode` is `"remote"` and no filter value has been entered. This is used as the empty-filter source both on open and after the filter is cleared again.
520
509
  * @property {Object} filter.marker - Markers for embedding the filter value into the `url` for server-side filtering.
521
510
  * @property {string} filter.marker.open - Opening marker (e.g., `{`).
522
511
  * @property {string} filter.marker.close - Closing marker (e.g., `}`).
@@ -544,6 +533,7 @@ class Select extends CustomControl {
544
533
  * @property {Function} formatter.selection - Callback `(value, option) => string` to format the display text of selected values.
545
534
  * @property {Object} classes - CSS classes for various elements.
546
535
  * @property {string} classes.badge - CSS class for selection badges.
536
+ * @property {string} classes.badgeUnresolved - CSS class used for selection badges whose value could not be hydrated. By default this swaps the badge into a warning style while keeping the raw key visible.
547
537
  * @property {string} classes.statusOrRemoveBadge - CSS class for the status or remove badge.
548
538
  * @property {string} classes.remoteInfo - CSS class for the remote info badge.
549
539
  * @property {string} classes.noOptions - CSS class for the "no options" message.
@@ -625,6 +615,7 @@ class Select extends CustomControl {
625
615
 
626
616
  classes: {
627
617
  badge: "monster-badge-primary",
618
+ badgeUnresolved: "monster-badge-warning",
628
619
  statusOrRemoveBadge: "empty",
629
620
  remoteInfo: "monster-margin-start-4 monster-margin-top-4",
630
621
  noOptions: "monster-margin-top-4 monster-margin-start-4",
@@ -681,6 +672,7 @@ class Select extends CustomControl {
681
672
  // Clear the lookup cache
682
673
  this[lookupCacheSymbol].clear();
683
674
  this[lookupInProgressSymbol].clear();
675
+ this[unresolvedSelectionValuesSymbol].clear();
684
676
 
685
677
  setSelection
686
678
  .call(this, null)
@@ -702,7 +694,6 @@ class Select extends CustomControl {
702
694
  resetErrorAttribute(this);
703
695
 
704
696
  this[lazyLoadDoneSymbol] = false;
705
- this[runLookupOnceSymbol] = false;
706
697
 
707
698
  checkOptionState.call(this);
708
699
  calcAndSetOptionsDimension.call(this);
@@ -753,7 +744,9 @@ class Select extends CustomControl {
753
744
 
754
745
  if (self.getOption("url") !== null) {
755
746
  if (lazyLoadFlag || remoteFilterFlag) {
756
- lookupSelection.call(self);
747
+ if (self.getOption("lookup.url")) {
748
+ lookupSelection.call(self);
749
+ }
757
750
  } else {
758
751
  self
759
752
  .fetch()
@@ -1776,9 +1769,12 @@ function getTranslations() {
1776
1769
  }
1777
1770
 
1778
1771
  /**
1779
- * @private
1780
- */
1781
- /**
1772
+ * Hydrates the current selection once the component becomes visible.
1773
+ *
1774
+ * This path is used for initial hydration when remote or lazy-loaded options
1775
+ * are not yet present locally. It is intentionally limited to `lookup.url`
1776
+ * and does not fall back to the main remote option source.
1777
+ *
1782
1778
  * @private
1783
1779
  */
1784
1780
  function lookupSelection() {
@@ -1817,7 +1813,10 @@ function runSelectionLookupWhenVisible(self) {
1817
1813
  return;
1818
1814
  }
1819
1815
 
1820
- let url = self.getOption("lookup.url") || self.getOption("url");
1816
+ const url = self.getOption("lookup.url");
1817
+ if (!url) {
1818
+ return;
1819
+ }
1821
1820
  self[cleanupOptionsListSymbol] = false;
1822
1821
 
1823
1822
  if (self.getOption("lookup.grouping") === true) {
@@ -2237,22 +2236,120 @@ function parseSlotsToOptions() {
2237
2236
  * @return {*}
2238
2237
  */
2239
2238
  function buildSelectionLabel(value) {
2240
- // First, check the lookup cache.
2241
- if (this[lookupCacheSymbol].has(value)) {
2242
- return this[lookupCacheSymbol].get(value);
2243
- }
2244
-
2245
2239
  const strict = this.getOption("features.useStrictValueComparison") === true;
2246
2240
  const map = this[optionsMapSymbol];
2247
2241
  const key = strict ? value : String(value);
2248
2242
 
2249
2243
  if (map && map.has(key)) {
2244
+ if (clearUnresolvedSelectionValue.call(this, value)) {
2245
+ this[lookupCacheSymbol].delete(value);
2246
+ }
2250
2247
  return map.get(key);
2251
2248
  }
2252
2249
 
2250
+ if (this[lookupCacheSymbol].has(value)) {
2251
+ return this[lookupCacheSymbol].get(value);
2252
+ }
2253
+
2253
2254
  return undefined;
2254
2255
  }
2255
2256
 
2257
+ /**
2258
+ * @private
2259
+ * @param {*} value
2260
+ * @returns {*}
2261
+ */
2262
+ function getSelectionStateKey(value) {
2263
+ return this.getOption("features.useStrictValueComparison") === true
2264
+ ? value
2265
+ : String(value);
2266
+ }
2267
+
2268
+ /**
2269
+ * @private
2270
+ * @param {*} value
2271
+ * @returns {boolean}
2272
+ */
2273
+ function markSelectionAsUnresolved(value) {
2274
+ const key = getSelectionStateKey.call(this, value);
2275
+ if (this[unresolvedSelectionValuesSymbol].has(key)) {
2276
+ return false;
2277
+ }
2278
+
2279
+ this[unresolvedSelectionValuesSymbol].add(key);
2280
+ return true;
2281
+ }
2282
+
2283
+ /**
2284
+ * @private
2285
+ * @param {*} value
2286
+ * @returns {boolean}
2287
+ */
2288
+ function clearUnresolvedSelectionValue(value) {
2289
+ const key = getSelectionStateKey.call(this, value);
2290
+ return this[unresolvedSelectionValuesSymbol].delete(key);
2291
+ }
2292
+
2293
+ /**
2294
+ * @private
2295
+ * @param {*} value
2296
+ * @returns {boolean}
2297
+ */
2298
+ function isSelectionValueUnresolved(value) {
2299
+ const key = getSelectionStateKey.call(this, value);
2300
+ return this[unresolvedSelectionValuesSymbol].has(key);
2301
+ }
2302
+
2303
+ /**
2304
+ * @private
2305
+ * @param {*} value
2306
+ * @returns {string}
2307
+ */
2308
+ function getSelectionBadgeClass(value) {
2309
+ const classes = new TokenList(this.getOption("classes.badge"));
2310
+ if (!isSelectionValueUnresolved.call(this, value)) {
2311
+ return classes.toString();
2312
+ }
2313
+
2314
+ const unresolvedClasses = new TokenList(
2315
+ this.getOption("classes.badgeUnresolved"),
2316
+ );
2317
+ for (const token of classes.entries()) {
2318
+ if (token.startsWith("monster-badge-")) {
2319
+ classes.remove(token);
2320
+ }
2321
+ }
2322
+
2323
+ classes.add(unresolvedClasses.entries());
2324
+ return classes.toString();
2325
+ }
2326
+
2327
+ /**
2328
+ * @private
2329
+ * @param {*} value
2330
+ * @param {string} [preferredLabel]
2331
+ * @returns {{class: string, label: string, unresolved: boolean, value: *}}
2332
+ */
2333
+ function buildSelectionItem(value, preferredLabel) {
2334
+ let label = getSelectionLabel.call(this, value);
2335
+ const unresolved = isSelectionValueUnresolved.call(this, value);
2336
+ if (
2337
+ !unresolved &&
2338
+ `${label}` === `${value}` &&
2339
+ isString(preferredLabel) &&
2340
+ preferredLabel.length > 0
2341
+ ) {
2342
+ label = preferredLabel;
2343
+ }
2344
+
2345
+ return {
2346
+ label,
2347
+ value,
2348
+ class: getSelectionBadgeClass.call(this, value),
2349
+ unresolved,
2350
+ };
2351
+ }
2352
+
2256
2353
  /**
2257
2354
  * @private
2258
2355
  * @param {string} value The value to look up.
@@ -2278,6 +2375,7 @@ async function lookupValueAndCache(value) {
2278
2375
 
2279
2376
  let hasError = false;
2280
2377
  let found = false;
2378
+ let refreshSelection = false;
2281
2379
  try {
2282
2380
  this[lookupInProgressSymbol].set(value, true);
2283
2381
 
@@ -2309,28 +2407,47 @@ async function lookupValueAndCache(value) {
2309
2407
  }
2310
2408
 
2311
2409
  // The lookup might return more than the requested value, so we cache all of them.
2312
- if (!this[lookupCacheSymbol].has(itemValue)) {
2410
+ if (this[lookupCacheSymbol].get(itemValue) !== itemLabel) {
2313
2411
  this[lookupCacheSymbol].set(itemValue, itemLabel);
2314
- if (`${itemValue}` === `${value}`) {
2315
- found = true;
2316
- }
2412
+ refreshSelection = true;
2413
+ }
2414
+
2415
+ if (clearUnresolvedSelectionValue.call(this, itemValue)) {
2416
+ refreshSelection = true;
2417
+ }
2418
+
2419
+ if (`${itemValue}` === `${value}`) {
2420
+ found = true;
2317
2421
  }
2318
2422
  }
2319
2423
 
2320
2424
  if (!found && !this[lookupCacheSymbol].has(value)) {
2321
- const fallback = this.getOption("labels.cannot-be-loaded", value);
2322
- this[lookupCacheSymbol].set(value, `${fallback}`);
2425
+ this[lookupCacheSymbol].set(value, `${value}`);
2426
+ refreshSelection = true;
2323
2427
  }
2324
2428
 
2325
- // If the specific value was found, trigger a re-render of the selection.
2326
- if (found) {
2327
- await setSelection.call(this, this.getOption("selection"));
2429
+ if (!found && markSelectionAsUnresolved.call(this, value)) {
2430
+ refreshSelection = true;
2328
2431
  }
2329
2432
  } catch (e) {
2330
2433
  hasError = true;
2331
2434
  addErrorAttribute(this, e);
2435
+
2436
+ if (!this[lookupCacheSymbol].has(value)) {
2437
+ this[lookupCacheSymbol].set(value, `${value}`);
2438
+ refreshSelection = true;
2439
+ }
2440
+
2441
+ if (markSelectionAsUnresolved.call(this, value)) {
2442
+ refreshSelection = true;
2443
+ }
2332
2444
  } finally {
2333
2445
  this[lookupInProgressSymbol].delete(value);
2446
+
2447
+ if (refreshSelection) {
2448
+ await setSelection.call(this, this.getOption("selection"));
2449
+ }
2450
+
2334
2451
  if (hasError) {
2335
2452
  setStatusOrRemoveBadges.call(this, "error");
2336
2453
  } else {
@@ -2932,6 +3049,17 @@ function getSelectPopperPositionOptions() {
2932
3049
  getDefaultSelectPopperPositionProfile().placement;
2933
3050
  }
2934
3051
 
3052
+ if (
3053
+ resolveParentPopperContentBoundary(
3054
+ this[controlElementSymbol],
3055
+ this[popperElementSymbol],
3056
+ )
3057
+ ) {
3058
+ // Nested selects inside another popper must position against the viewport
3059
+ // so the parent content wrapper does not become their clipping boundary.
3060
+ popperOptions.strategy = "fixed";
3061
+ }
3062
+
2935
3063
  return popperOptions;
2936
3064
  }
2937
3065
 
@@ -3178,12 +3306,6 @@ function filterFromRemote() {
3178
3306
  return Promise.reject(new Error("Missing Filter Element."));
3179
3307
  }
3180
3308
 
3181
- const url = this.getOption("url");
3182
- if (!url) {
3183
- addErrorAttribute(this, "Missing URL for Remote Filter.");
3184
- return Promise.reject(new Error("Missing URL for Remote Filter."));
3185
- }
3186
-
3187
3309
  let filterValue;
3188
3310
  let showFlag = false;
3189
3311
 
@@ -3207,6 +3329,16 @@ function filterFromRemote() {
3207
3329
  page: this[currentPageSymbol] || 1,
3208
3330
  };
3209
3331
 
3332
+ if (shouldUseDefaultOptionsUrl.call(this, filterValue)) {
3333
+ return loadDefaultOptionsFromUrl.call(this, showFlag);
3334
+ }
3335
+
3336
+ const url = this.getOption("url");
3337
+ if (!url) {
3338
+ addErrorAttribute(this, "Missing URL for Remote Filter.");
3339
+ return Promise.reject(new Error("Missing URL for Remote Filter."));
3340
+ }
3341
+
3210
3342
  return filterFromRemoteByValue.call(this, url, params, showFlag);
3211
3343
  }
3212
3344
 
@@ -3216,7 +3348,8 @@ function filterFromRemote() {
3216
3348
  * @param {object} params
3217
3349
  * @returns {string}
3218
3350
  */
3219
- function formatURL(url, params = {}) {
3351
+ function formatURL(url, params = {}, formatOptions = {}) {
3352
+ const preserveEmptyFilter = formatOptions?.preserveEmptyFilter === true;
3220
3353
  const paramsDefaults = this.getOption("filter.paramsDefaults");
3221
3354
  const externalParams = this.getOption("filter.params");
3222
3355
  if (isObject(paramsDefaults) || isObject(externalParams)) {
@@ -3244,7 +3377,7 @@ function formatURL(url, params = {}) {
3244
3377
  if (
3245
3378
  params.filter === undefined ||
3246
3379
  params.filter === null ||
3247
- params.filter === ""
3380
+ (params.filter === "" && preserveEmptyFilter !== true)
3248
3381
  ) {
3249
3382
  const defaultValue = this.getOption("filter.defaultValue");
3250
3383
  if (defaultValue === undefined || defaultValue === null) {
@@ -3284,9 +3417,14 @@ function formatURL(url, params = {}) {
3284
3417
  * @param {boolean} [openPopper] Flag indicating whether to open the popper.
3285
3418
  * @return {string} The formatted URL with the applied filters and markers.
3286
3419
  */
3287
- function filterFromRemoteByValue(optionUrl, params, openPopper) {
3420
+ function filterFromRemoteByValue(
3421
+ optionUrl,
3422
+ params,
3423
+ openPopper,
3424
+ formatOptions = {},
3425
+ ) {
3288
3426
  return new Processing(() => {
3289
- let url = formatURL.call(this, optionUrl, params);
3427
+ let url = formatURL.call(this, optionUrl, params, formatOptions);
3290
3428
 
3291
3429
  if (url.indexOf(disabledRequestMarker.toString()) !== -1) {
3292
3430
  this.setOption("total", null);
@@ -3400,6 +3538,51 @@ function getCurrentFilterValue() {
3400
3538
  return "";
3401
3539
  }
3402
3540
 
3541
+ function shouldUseDefaultOptionsUrl(filterValue) {
3542
+ if (!isString(this.getOption("filter.defaultOptionsUrl"))) {
3543
+ return false;
3544
+ }
3545
+
3546
+ if (filterValue === undefined || filterValue === null) {
3547
+ return true;
3548
+ }
3549
+
3550
+ if (isString(filterValue)) {
3551
+ return filterValue.trim() === "";
3552
+ }
3553
+
3554
+ return false;
3555
+ }
3556
+
3557
+ function loadDefaultOptionsFromUrl(openPopper = false) {
3558
+ const url = this.getOption("filter.defaultOptionsUrl");
3559
+ if (!isString(url)) {
3560
+ return Promise.resolve(false);
3561
+ }
3562
+
3563
+ this[cleanupOptionsListSymbol] = true;
3564
+
3565
+ return filterFromRemoteByValue
3566
+ .call(
3567
+ this,
3568
+ url,
3569
+ {
3570
+ filter: "",
3571
+ page: this[currentPageSymbol] || 1,
3572
+ },
3573
+ openPopper,
3574
+ {
3575
+ preserveEmptyFilter: true,
3576
+ },
3577
+ )
3578
+ .then(() => {
3579
+ if (isPositionedPopperOpen(this[popperElementSymbol])) {
3580
+ setStatusOrRemoveBadges.call(this, "open");
3581
+ }
3582
+ return true;
3583
+ });
3584
+ }
3585
+
3403
3586
  /**
3404
3587
  * @private
3405
3588
  */
@@ -3519,10 +3702,7 @@ function gatherState() {
3519
3702
  );
3520
3703
 
3521
3704
  for (const e of elements) {
3522
- selection.push({
3523
- label: getSelectionLabel.call(this, e.value),
3524
- value: e.value,
3525
- });
3705
+ selection.push(buildSelectionItem.call(this, e.value));
3526
3706
  }
3527
3707
 
3528
3708
  filteredSelection = selection;
@@ -3539,10 +3719,7 @@ function gatherState() {
3539
3719
  (sel) => !currentInputValues.has(sel.value),
3540
3720
  );
3541
3721
  for (const input of checkedElements) {
3542
- filteredSelection.push({
3543
- label: getSelectionLabel.call(this, input.value),
3544
- value: input.value,
3545
- });
3722
+ filteredSelection.push(buildSelectionItem.call(this, input.value));
3546
3723
  }
3547
3724
  }
3548
3725
 
@@ -3821,16 +3998,10 @@ function convertValueToSelection(value) {
3821
3998
  }
3822
3999
 
3823
4000
  if (isString(value) || isInteger(value)) {
3824
- selection.push({
3825
- label: getSelectionLabel.call(this, value),
3826
- value: value,
3827
- });
4001
+ selection.push(buildSelectionItem.call(this, value));
3828
4002
  } else if (isArray(value)) {
3829
4003
  for (const v of value) {
3830
- selection.push({
3831
- label: getSelectionLabel.call(this, v),
3832
- value: v,
3833
- });
4004
+ selection.push(buildSelectionItem.call(this, v));
3834
4005
  }
3835
4006
 
3836
4007
  value = value.join(",");
@@ -3955,8 +4126,6 @@ function areSelectionValuesEqual(current, next) {
3955
4126
  * @returns {Promise<unknown | void>}
3956
4127
  */
3957
4128
  function setSelection(selection) {
3958
- const self = this;
3959
-
3960
4129
  if (isString(selection) || isInteger(selection)) {
3961
4130
  const result = convertValueToSelection.call(this, selection);
3962
4131
  selection = result?.selection;
@@ -3973,15 +4142,9 @@ function setSelection(selection) {
3973
4142
  continue;
3974
4143
  }
3975
4144
 
3976
- let l = getSelectionLabel.call(this, selection[i].value);
3977
- if (l === selection[i].value) {
3978
- l = selection[i].label;
3979
- }
3980
-
3981
- resultSelection.push({
3982
- label: l,
3983
- value: selection[i].value,
3984
- });
4145
+ resultSelection.push(
4146
+ buildSelectionItem.call(this, selection[i].value, selection[i].label),
4147
+ );
3985
4148
  }
3986
4149
 
3987
4150
  selection = resultSelection;
@@ -4016,17 +4179,6 @@ function setSelection(selection) {
4016
4179
  fireEvent(this, "change"); // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/291
4017
4180
  }
4018
4181
 
4019
- if (this[runLookupOnceSymbol] !== true && selection.length > 0) {
4020
- this[runLookupOnceSymbol] = true;
4021
-
4022
- const lazyLoadFlag =
4023
- this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
4024
- const remoteFilterFlag = getFilterMode.call(this) === FILTER_MODE_REMOTE;
4025
- if (lazyLoadFlag || remoteFilterFlag) {
4026
- lookupSelection.call(self);
4027
- }
4028
- }
4029
-
4030
4182
  return new Processing(() => {
4031
4183
  const CLASSNAME = "selected";
4032
4184
 
@@ -4178,12 +4330,6 @@ function show() {
4178
4330
  return;
4179
4331
  }
4180
4332
 
4181
- const hasDefaultOptionsUrl = isString(
4182
- this.getOption("filter.defaultOptionsUrl"),
4183
- );
4184
-
4185
- initDefaultOptionsFromUrl.call(this);
4186
-
4187
4333
  const hasPopperFilterFlag =
4188
4334
  this.getOption("filter.position") === FILTER_POSITION_POPPER &&
4189
4335
  getFilterMode.call(this) !== FILTER_MODE_DISABLED;
@@ -4206,17 +4352,23 @@ function show() {
4206
4352
  registerWithHost.call(this);
4207
4353
 
4208
4354
  new Processing(() => {
4209
- if (!self?.[remoteFilterFirstOpendSymbol]) {
4210
- self[remoteFilterFirstOpendSymbol] = true;
4355
+ const shouldLoadRemoteOptions =
4356
+ getFilterMode.call(self) === FILTER_MODE_REMOTE &&
4357
+ getOptionElements.call(self).length === 0;
4211
4358
 
4212
- if (!hasDefaultOptionsUrl) {
4213
- setTimeout(() => {
4214
- self[cleanupOptionsListSymbol] = true;
4215
- filterFromRemote.call(self).catch((e) => {
4216
- addErrorAttribute(self, e);
4217
- });
4218
- }, 0);
4219
- }
4359
+ if (shouldUseDefaultOptionsUrl.call(self, getCurrentFilterValue.call(self))) {
4360
+ setTimeout(() => {
4361
+ loadDefaultOptionsFromUrl.call(self).catch((e) => {
4362
+ addErrorAttribute(self, e);
4363
+ });
4364
+ }, 0);
4365
+ } else if (shouldLoadRemoteOptions) {
4366
+ setTimeout(() => {
4367
+ self[cleanupOptionsListSymbol] = true;
4368
+ filterFromRemote.call(self).catch((e) => {
4369
+ addErrorAttribute(self, e);
4370
+ });
4371
+ }, 0);
4220
4372
  }
4221
4373
  calcAndSetOptionsDimension.call(this);
4222
4374
  focusFilter.call(this);
@@ -4280,31 +4432,6 @@ function unregisterFromHost() {
4280
4432
  this[hostElementSymbol].unregisterDismissable?.(this);
4281
4433
  }
4282
4434
 
4283
- function initDefaultOptionsFromUrl() {
4284
- const url = this.getOption("filter.defaultOptionsUrl");
4285
- if (!url) {
4286
- return;
4287
- }
4288
-
4289
- this.setOption("filter.defaultOptionsUrl", null);
4290
-
4291
- fetchData
4292
- .call(this, url)
4293
- .then((data) => {
4294
- this[cleanupOptionsListSymbol] = false;
4295
- importOptionsIntern.call(this, data);
4296
- setStatusOrRemoveBadges.call(this, "open");
4297
- initTotal.call(this, data);
4298
- })
4299
- .catch((e) => {
4300
- addErrorAttribute(this, e);
4301
- setStatusOrRemoveBadges.call(this, "error");
4302
- });
4303
- }
4304
-
4305
- /**
4306
- * @private
4307
- */
4308
4435
  /**
4309
4436
  * @private
4310
4437
  */
@@ -4915,7 +5042,8 @@ function getTemplate() {
4915
5042
  part="badge"
4916
5043
  data-monster-attributes="
4917
5044
  data-monster-value path:selection | index:value,
4918
- class path:classes | index:badge,
5045
+ data-monster-unresolved path:selection | index:unresolved,
5046
+ class path:selection | index:class,
4919
5047
  part path:type | suffix:-option | prefix: form-" tabindex="-1">
4920
5048
  <div data-monster-replace="path:selection | index:label" part="badge-label"
4921
5049
  data-monster-role="badge-label"></div>
@@ -262,9 +262,9 @@ div[data-monster-role=selection] {
262
262
  max-width: 100%;
263
263
  min-width: 0;
264
264
  flex-grow: 1;
265
+ scrollbar-gutter: stable;
265
266
  scrollbar-color: var(--monster-color-primary-1) var(--monster-bg-color-primary-1);
266
267
  scrollbar-width: thin;
267
- transition: height 0.3s ease;
268
268
  overflow-x: hidden;
269
269
  }
270
270
 
@@ -24,7 +24,7 @@ const SelectStyleSheet = new CSSStyleSheet();
24
24
  try {
25
25
  SelectStyleSheet.insertRule(`
26
26
  @layer select {
27
- .block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-border-primary-1,.monster-border-primary-2,.monster-border-primary-3,.monster-border-primary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-0{border-radius:0;border-style:none;border-width:0}.monster-border-primary-1{border-color:var(--monster-bg-color-primary-1)}.monster-border-primary-2{border-color:var(--monster-bg-color-primary-2)}.monster-border-primary-3{border-color:var(--monster-bg-color-primary-3)}.monster-border-primary-4{border-color:var(--monster-bg-color-primary-4)}.monster-border-secondary-1,.monster-border-secondary-2,.monster-border-secondary-3,.monster-border-secondary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-secondary-1{border-color:var(--monster-bg-color-secondary-1)}.monster-border-secondary-2{border-color:var(--monster-bg-color-secondary-2)}.monster-border-secondary-3{border-color:var(--monster-bg-color-secondary-3)}.monster-border-secondary-4{border-color:var(--monster-bg-color-secondary-4)}.monster-border-tertiary-1,.monster-border-tertiary-2,.monster-border-tertiary-3,.monster-border-tertiary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-tertiary-1{border-color:var(--monster-bg-color-tertiary-1)}.monster-border-tertiary-2{border-color:var(--monster-bg-color-tertiary-2)}.monster-border-tertiary-3{border-color:var(--monster-bg-color-tertiary-3)}.monster-border-tertiary-4{border-color:var(--monster-bg-color-tertiary-4)}[data-monster-role=control]{width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}.monster-badge-primary{padding:.25em .4em}.monster-badge-primary,.monster-badge-primary-pill{background-color:var(--monster-bg-color-primary-4);border-radius:.25rem;color:var(--monster-color-primary-4);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-primary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-secondary{padding:.25em .4em}.monster-badge-secondary,.monster-badge-secondary-pill{background-color:var(--monster-bg-color-secondary-3);border-radius:.25rem;color:var(--monster-color-secondary-3);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-secondary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-tertiary{padding:.25em .4em}.monster-badge-tertiary,.monster-badge-tertiary-pill{background-color:var(--monster-bg-color-tertiary-3);border-radius:.25rem;color:var(--monster-color-tertiary-3);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-tertiary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-destructive{padding:.25em .4em}.monster-badge-destructive,.monster-badge-destructive-pill{background-color:var(--monster-bg-color-destructive-1);border-radius:.25rem;color:var(--monster-color-destructive-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-destructive-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-success{padding:.25em .4em}.monster-badge-success,.monster-badge-success-pill{background-color:var(--monster-bg-color-success-1);border-radius:.25rem;color:var(--monster-color-success-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-success-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-warning{padding:.25em .4em}.monster-badge-warning,.monster-badge-warning-pill{background-color:var(--monster-bg-color-warning-1);border-radius:.25rem;color:var(--monster-color-warning-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-warning-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-error{padding:.25em .4em}.monster-badge-error,.monster-badge-error-pill{background-color:var(--monster-bg-color-error-1);border-radius:.25rem;color:var(--monster-color-error-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-error-pill{border-radius:10rem;padding:.25em .6em}.monster-margin-0{margin:var(--monster-space-0)}.monster-margin-top-0{margin-top:var(--monster-space-0)}.monster-margin-end-0{margin-right:var(--monster-space-0)}.monster-margin-bottom-0{margin-bottom:var(--monster-space-0)}.monster-margin-start-0{margin-left:var(--monster-space-0)}.monster-padding-0{padding:var(--monster-space-0)}.monster-padding-top-0{padding-top:var(--monster-space-0)}.monster-padding-end-0{padding-right:var(--monster-space-0)}.monster-padding-bottom-0{padding-bottom:var(--monster-space-0)}.monster-padding-start-0{padding-left:var(--monster-space-0)}.monster-margin-1{margin:var(--monster-space-1)}.monster-margin-top-1{margin-top:var(--monster-space-1)}.monster-margin-end-1{margin-right:var(--monster-space-1)}.monster-margin-bottom-1{margin-bottom:var(--monster-space-1)}.monster-margin-start-1{margin-left:var(--monster-space-1)}.monster-padding-1{padding:var(--monster-space-1)}.monster-padding-top-1{padding-top:var(--monster-space-1)}.monster-padding-end-1{padding-right:var(--monster-space-1)}.monster-padding-bottom-1{padding-bottom:var(--monster-space-1)}.monster-padding-start-1{padding-left:var(--monster-space-1)}.monster-margin-2{margin:var(--monster-space-2)}.monster-margin-top-2{margin-top:var(--monster-space-2)}.monster-margin-end-2{margin-right:var(--monster-space-2)}.monster-margin-bottom-2{margin-bottom:var(--monster-space-2)}.monster-margin-start-2{margin-left:var(--monster-space-2)}.monster-padding-2{padding:var(--monster-space-2)}.monster-padding-top-2{padding-top:var(--monster-space-2)}.monster-padding-end-2{padding-right:var(--monster-space-2)}.monster-padding-bottom-2{padding-bottom:var(--monster-space-2)}.monster-padding-start-2{padding-left:var(--monster-space-2)}.monster-margin-3{margin:var(--monster-space-3)}.monster-margin-top-3{margin-top:var(--monster-space-3)}.monster-margin-end-3{margin-right:var(--monster-space-3)}.monster-margin-bottom-3{margin-bottom:var(--monster-space-3)}.monster-margin-start-3{margin-left:var(--monster-space-3)}.monster-padding-3{padding:var(--monster-space-3)}.monster-padding-top-3{padding-top:var(--monster-space-3)}.monster-padding-end-3{padding-right:var(--monster-space-3)}.monster-padding-bottom-3{padding-bottom:var(--monster-space-3)}.monster-padding-start-3{padding-left:var(--monster-space-3)}.monster-margin-4{margin:var(--monster-space-4)}.monster-margin-top-4{margin-top:var(--monster-space-4)}.monster-margin-end-4{margin-right:var(--monster-space-4)}.monster-margin-bottom-4{margin-bottom:var(--monster-space-4)}.monster-margin-start-4{margin-left:var(--monster-space-4)}.monster-padding-4{padding:var(--monster-space-4)}.monster-padding-top-4{padding-top:var(--monster-space-4)}.monster-padding-end-4{padding-right:var(--monster-space-4)}.monster-padding-bottom-4{padding-bottom:var(--monster-space-4)}.monster-padding-start-4{padding-left:var(--monster-space-4)}.monster-margin-5{margin:var(--monster-space-5)}.monster-margin-top-5{margin-top:var(--monster-space-5)}.monster-margin-end-5{margin-right:var(--monster-space-5)}.monster-margin-bottom-5{margin-bottom:var(--monster-space-5)}.monster-margin-start-5{margin-left:var(--monster-space-5)}.monster-padding-5{padding:var(--monster-space-5)}.monster-padding-top-5{padding-top:var(--monster-space-5)}.monster-padding-end-5{padding-right:var(--monster-space-5)}.monster-padding-bottom-5{padding-bottom:var(--monster-space-5)}.monster-padding-start-5{padding-left:var(--monster-space-5)}.monster-margin-6{margin:var(--monster-space-6)}.monster-margin-top-6{margin-top:var(--monster-space-6)}.monster-margin-end-6{margin-right:var(--monster-space-6)}.monster-margin-bottom-6{margin-bottom:var(--monster-space-6)}.monster-margin-start-6{margin-left:var(--monster-space-6)}.monster-padding-6{padding:var(--monster-space-6)}.monster-padding-top-6{padding-top:var(--monster-space-6)}.monster-padding-end-6{padding-right:var(--monster-space-6)}.monster-padding-bottom-6{padding-bottom:var(--monster-space-6)}.monster-padding-start-6{padding-left:var(--monster-space-6)}.monster-margin-7{margin:var(--monster-space-7)}.monster-margin-top-7{margin-top:var(--monster-space-7)}.monster-margin-end-7{margin-right:var(--monster-space-7)}.monster-margin-bottom-7{margin-bottom:var(--monster-space-7)}.monster-margin-start-7{margin-left:var(--monster-space-7)}.monster-padding-7{padding:var(--monster-space-7)}.monster-padding-top-7{padding-top:var(--monster-space-7)}.monster-padding-end-7{padding-right:var(--monster-space-7)}.monster-padding-bottom-7{padding-bottom:var(--monster-space-7)}.monster-padding-start-7{padding-left:var(--monster-space-7)}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:none;overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=container]{-webkit-appearance:none;-moz-appearance:none;appearance:none;flex:4 0 90%;min-height:1.4em;overflow:auto;scrollbar-color:var(--monster-color-primary-1) var(--monster-bg-color-primary-1);scrollbar-width:thin;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;width:100%}.d-none{display:none!important}div[data-monster-role=no-options] span,div[data-monster-role=remote-info] span{text-wrap:balance}div[data-monster-role=control]{display:flex;height:100%;position:relative}[data-monster-role=container].open{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\")}[data-monster-role=container].clear,[data-monster-role=container].open{background-color:var(--monster-bg-color-primary-2);-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:.8em;mask-size:.8em}[data-monster-role=container].clear{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}[data-monster-role=control]{accent-color:var(--monster-color-secondary-2);background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-theme-control-border-color);-o-border-image:initial;border-image:initial;border-radius:var(--monster-theme-control-border-radius);border-style:var(--monster-theme-control-border-style);border-width:var(--monster-theme-control-border-width);box-sizing:border-box;color:var(--monster-color-primary-1);display:flex;font-family:inherit;font-size:100%;margin:0;outline:none;padding:.4rem .6rem;width:-webkit-fill-available;width:-moz-available;width:fill-available}@media (prefers-color-scheme:light){[data-monster-role=control]{background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-3);color:var(--monster-color-primary-1)}[data-monster-role=control]:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px}}[data-monster-role=control]:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}:host([disabled]) [data-monster-role=control]{cursor:not-allowed}:host([disabled]) [data-monster-role=status-or-remove-badges],[data-monster-role=control][disabled] [data-monster-role=status-or-remove-badges]{display:none}div[data-monster-role=selection]{align-items:center;display:flex;flex-direction:row;flex-wrap:wrap;gap:5px;justify-content:flex-start;margin:5px}[data-monster-role=option-control]{margin-right:8px}[data-monster-role=badge]{display:inline-flex}[data-monster-role=badge-label]{align-content:center;align-items:center;display:flex;flex-direction:row;gap:7px;justify-content:space-between}[data-monster-role=filter],[data-monster-role=popper-filter]{display:flex;flex-grow:200;order:99999999;visibility:hidden}[data-monster-role=filter].active{background-color:var(--monster-bg-color-primary-2);border:0;border-color:var(--monster-bg-color-primary-3);border-bottom:1px solid var(--monster-bg-color-primary-3);color:var(--monster-color-primary-2);min-width:40%;outline:none;visibility:visible}.active[data-monster-role=filter][name=popper-filter]{height:1.5em;margin:2.5em;padding:2px;width:calc(100% - var(--monster-border-width)*2)}.option-filter-control{align-items:center;background-color:var(--monster-bg-color-primary-2);display:flex;height:2.5em;margin:-1.1em -1.1em .3em}[data-monster-role=remove-badge]{background-color:var(--monster-bg-color-primary-2);height:16px;margin-left:5px;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");order:2}[data-monster-role=remove-badge],[data-monster-role=status-or-remove-badges]{-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:.8em;mask-size:.8em;min-height:16px;width:16px}[data-monster-role=status-or-remove-badges]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}.open[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\")}.empty[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-dash-circle' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-dash-circle' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8'/%3E%3C/svg%3E\")}.clear[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}.error[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-error-1);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\")}@media (prefers-color-scheme:dark){.error[data-monster-role=status-or-remove-badges]{background-color:var(--monster-color-error-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\")}}.loading[data-monster-role=status-or-remove-badges]{animation-duration:1s;animation-iteration-count:infinite;animation-name:activity;animation-timing-function:cubic-bezier(0,0,.2,1);background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='activity' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='activity' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3C/svg%3E\")}@keyframes activity{0%{transform:scale(1)}50%{transform:scale(.1)}to{transform:scale(1)}}[data-monster-role=options]{flex-direction:column;flex-grow:1;overflow-x:hidden;scrollbar-color:var(--monster-color-primary-1) var(--monster-bg-color-primary-1);scrollbar-width:thin;transition:height .3s ease}[data-monster-role=option],[data-monster-role=options]{box-sizing:border-box;display:flex;max-width:100%;min-width:0;width:100%}[data-monster-role=option]{align-items:center;padding:6px 5px}[data-monster-role=option] label{justify-content:flex-start}[data-monster-role=option] label,[data-monster-role=option] label>div{align-items:center;display:flex;flex-direction:row;max-width:100%;min-width:0;width:100%}[data-monster-role=option] label>div{justify-content:space-between;outline:none}[part=option-label]{max-width:100%;min-width:0;overflow-wrap:anywhere;word-break:break-word}.selected{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=option][data-monster-filtered=true],[data-monster-role=option][data-monster-visibility=hidden]{display:none}[data-monster-role=option][data-monster-focused=true]{outline:1px dashed var(--monster-color-selection-2);outline-offset:-2px}@media (prefers-color-scheme:dark){[data-monster-role=option][data-monster-focused=true]{outline:1px dashed var(--monster-color-selection-4)}}[data-monster-role=filter]::-moz-placeholder{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=filter]::placeholder{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=option]>input:focus,[data-monster-role=option]>label:focus{outline:none}[data-monster-role=selection-messages]:empty:before,[data-monster-role=summary-messages]:empty:before{content:\"\u00A0\"}.in-button-bar{border-color:var(--monster-bg-color-primary-4)!important;border-style:var(--monster-border-style)!important;border-width:var(--monster-border-width)!important}[data-monster-role=pagination]::part(nav){justify-content:flex-start}[data-monster-role=pagination]::part(list){margin-bottom:0;margin-top:0}
27
+ .block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-border-primary-1,.monster-border-primary-2,.monster-border-primary-3,.monster-border-primary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-0{border-radius:0;border-style:none;border-width:0}.monster-border-primary-1{border-color:var(--monster-bg-color-primary-1)}.monster-border-primary-2{border-color:var(--monster-bg-color-primary-2)}.monster-border-primary-3{border-color:var(--monster-bg-color-primary-3)}.monster-border-primary-4{border-color:var(--monster-bg-color-primary-4)}.monster-border-secondary-1,.monster-border-secondary-2,.monster-border-secondary-3,.monster-border-secondary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-secondary-1{border-color:var(--monster-bg-color-secondary-1)}.monster-border-secondary-2{border-color:var(--monster-bg-color-secondary-2)}.monster-border-secondary-3{border-color:var(--monster-bg-color-secondary-3)}.monster-border-secondary-4{border-color:var(--monster-bg-color-secondary-4)}.monster-border-tertiary-1,.monster-border-tertiary-2,.monster-border-tertiary-3,.monster-border-tertiary-4{border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width)}.monster-border-tertiary-1{border-color:var(--monster-bg-color-tertiary-1)}.monster-border-tertiary-2{border-color:var(--monster-bg-color-tertiary-2)}.monster-border-tertiary-3{border-color:var(--monster-bg-color-tertiary-3)}.monster-border-tertiary-4{border-color:var(--monster-bg-color-tertiary-4)}[data-monster-role=control]{width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}.monster-badge-primary{padding:.25em .4em}.monster-badge-primary,.monster-badge-primary-pill{background-color:var(--monster-bg-color-primary-4);border-radius:.25rem;color:var(--monster-color-primary-4);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-primary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-secondary{padding:.25em .4em}.monster-badge-secondary,.monster-badge-secondary-pill{background-color:var(--monster-bg-color-secondary-3);border-radius:.25rem;color:var(--monster-color-secondary-3);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-secondary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-tertiary{padding:.25em .4em}.monster-badge-tertiary,.monster-badge-tertiary-pill{background-color:var(--monster-bg-color-tertiary-3);border-radius:.25rem;color:var(--monster-color-tertiary-3);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-tertiary-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-destructive{padding:.25em .4em}.monster-badge-destructive,.monster-badge-destructive-pill{background-color:var(--monster-bg-color-destructive-1);border-radius:.25rem;color:var(--monster-color-destructive-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-destructive-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-success{padding:.25em .4em}.monster-badge-success,.monster-badge-success-pill{background-color:var(--monster-bg-color-success-1);border-radius:.25rem;color:var(--monster-color-success-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-success-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-warning{padding:.25em .4em}.monster-badge-warning,.monster-badge-warning-pill{background-color:var(--monster-bg-color-warning-1);border-radius:.25rem;color:var(--monster-color-warning-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-warning-pill{border-radius:10rem;padding:.25em .6em}.monster-badge-error{padding:.25em .4em}.monster-badge-error,.monster-badge-error-pill{background-color:var(--monster-bg-color-error-1);border-radius:.25rem;color:var(--monster-color-error-1);display:inline-block;font-size:75%;font-weight:700;line-height:1;text-align:center;text-decoration:none;vertical-align:baseline;white-space:nowrap}.monster-badge-error-pill{border-radius:10rem;padding:.25em .6em}.monster-margin-0{margin:var(--monster-space-0)}.monster-margin-top-0{margin-top:var(--monster-space-0)}.monster-margin-end-0{margin-right:var(--monster-space-0)}.monster-margin-bottom-0{margin-bottom:var(--monster-space-0)}.monster-margin-start-0{margin-left:var(--monster-space-0)}.monster-padding-0{padding:var(--monster-space-0)}.monster-padding-top-0{padding-top:var(--monster-space-0)}.monster-padding-end-0{padding-right:var(--monster-space-0)}.monster-padding-bottom-0{padding-bottom:var(--monster-space-0)}.monster-padding-start-0{padding-left:var(--monster-space-0)}.monster-margin-1{margin:var(--monster-space-1)}.monster-margin-top-1{margin-top:var(--monster-space-1)}.monster-margin-end-1{margin-right:var(--monster-space-1)}.monster-margin-bottom-1{margin-bottom:var(--monster-space-1)}.monster-margin-start-1{margin-left:var(--monster-space-1)}.monster-padding-1{padding:var(--monster-space-1)}.monster-padding-top-1{padding-top:var(--monster-space-1)}.monster-padding-end-1{padding-right:var(--monster-space-1)}.monster-padding-bottom-1{padding-bottom:var(--monster-space-1)}.monster-padding-start-1{padding-left:var(--monster-space-1)}.monster-margin-2{margin:var(--monster-space-2)}.monster-margin-top-2{margin-top:var(--monster-space-2)}.monster-margin-end-2{margin-right:var(--monster-space-2)}.monster-margin-bottom-2{margin-bottom:var(--monster-space-2)}.monster-margin-start-2{margin-left:var(--monster-space-2)}.monster-padding-2{padding:var(--monster-space-2)}.monster-padding-top-2{padding-top:var(--monster-space-2)}.monster-padding-end-2{padding-right:var(--monster-space-2)}.monster-padding-bottom-2{padding-bottom:var(--monster-space-2)}.monster-padding-start-2{padding-left:var(--monster-space-2)}.monster-margin-3{margin:var(--monster-space-3)}.monster-margin-top-3{margin-top:var(--monster-space-3)}.monster-margin-end-3{margin-right:var(--monster-space-3)}.monster-margin-bottom-3{margin-bottom:var(--monster-space-3)}.monster-margin-start-3{margin-left:var(--monster-space-3)}.monster-padding-3{padding:var(--monster-space-3)}.monster-padding-top-3{padding-top:var(--monster-space-3)}.monster-padding-end-3{padding-right:var(--monster-space-3)}.monster-padding-bottom-3{padding-bottom:var(--monster-space-3)}.monster-padding-start-3{padding-left:var(--monster-space-3)}.monster-margin-4{margin:var(--monster-space-4)}.monster-margin-top-4{margin-top:var(--monster-space-4)}.monster-margin-end-4{margin-right:var(--monster-space-4)}.monster-margin-bottom-4{margin-bottom:var(--monster-space-4)}.monster-margin-start-4{margin-left:var(--monster-space-4)}.monster-padding-4{padding:var(--monster-space-4)}.monster-padding-top-4{padding-top:var(--monster-space-4)}.monster-padding-end-4{padding-right:var(--monster-space-4)}.monster-padding-bottom-4{padding-bottom:var(--monster-space-4)}.monster-padding-start-4{padding-left:var(--monster-space-4)}.monster-margin-5{margin:var(--monster-space-5)}.monster-margin-top-5{margin-top:var(--monster-space-5)}.monster-margin-end-5{margin-right:var(--monster-space-5)}.monster-margin-bottom-5{margin-bottom:var(--monster-space-5)}.monster-margin-start-5{margin-left:var(--monster-space-5)}.monster-padding-5{padding:var(--monster-space-5)}.monster-padding-top-5{padding-top:var(--monster-space-5)}.monster-padding-end-5{padding-right:var(--monster-space-5)}.monster-padding-bottom-5{padding-bottom:var(--monster-space-5)}.monster-padding-start-5{padding-left:var(--monster-space-5)}.monster-margin-6{margin:var(--monster-space-6)}.monster-margin-top-6{margin-top:var(--monster-space-6)}.monster-margin-end-6{margin-right:var(--monster-space-6)}.monster-margin-bottom-6{margin-bottom:var(--monster-space-6)}.monster-margin-start-6{margin-left:var(--monster-space-6)}.monster-padding-6{padding:var(--monster-space-6)}.monster-padding-top-6{padding-top:var(--monster-space-6)}.monster-padding-end-6{padding-right:var(--monster-space-6)}.monster-padding-bottom-6{padding-bottom:var(--monster-space-6)}.monster-padding-start-6{padding-left:var(--monster-space-6)}.monster-margin-7{margin:var(--monster-space-7)}.monster-margin-top-7{margin-top:var(--monster-space-7)}.monster-margin-end-7{margin-right:var(--monster-space-7)}.monster-margin-bottom-7{margin-bottom:var(--monster-space-7)}.monster-margin-start-7{margin-left:var(--monster-space-7)}.monster-padding-7{padding:var(--monster-space-7)}.monster-padding-top-7{padding-top:var(--monster-space-7)}.monster-padding-end-7{padding-right:var(--monster-space-7)}.monster-padding-bottom-7{padding-bottom:var(--monster-space-7)}.monster-padding-start-7{padding-left:var(--monster-space-7)}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:none;overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=container]{-webkit-appearance:none;-moz-appearance:none;appearance:none;flex:4 0 90%;min-height:1.4em;overflow:auto;scrollbar-color:var(--monster-color-primary-1) var(--monster-bg-color-primary-1);scrollbar-width:thin;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;width:100%}.d-none{display:none!important}div[data-monster-role=no-options] span,div[data-monster-role=remote-info] span{text-wrap:balance}div[data-monster-role=control]{display:flex;height:100%;position:relative}[data-monster-role=container].open{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\")}[data-monster-role=container].clear,[data-monster-role=container].open{background-color:var(--monster-bg-color-primary-2);-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:.8em;mask-size:.8em}[data-monster-role=container].clear{-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}[data-monster-role=control]{accent-color:var(--monster-color-secondary-2);background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-theme-control-border-color);-o-border-image:initial;border-image:initial;border-radius:var(--monster-theme-control-border-radius);border-style:var(--monster-theme-control-border-style);border-width:var(--monster-theme-control-border-width);box-sizing:border-box;color:var(--monster-color-primary-1);display:flex;font-family:inherit;font-size:100%;margin:0;outline:none;padding:.4rem .6rem;width:-webkit-fill-available;width:-moz-available;width:fill-available}@media (prefers-color-scheme:light){[data-monster-role=control]{background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-3);color:var(--monster-color-primary-1)}[data-monster-role=control]:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px}}[data-monster-role=control]:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}:host([disabled]) [data-monster-role=control]{cursor:not-allowed}:host([disabled]) [data-monster-role=status-or-remove-badges],[data-monster-role=control][disabled] [data-monster-role=status-or-remove-badges]{display:none}div[data-monster-role=selection]{align-items:center;display:flex;flex-direction:row;flex-wrap:wrap;gap:5px;justify-content:flex-start;margin:5px}[data-monster-role=option-control]{margin-right:8px}[data-monster-role=badge]{display:inline-flex}[data-monster-role=badge-label]{align-content:center;align-items:center;display:flex;flex-direction:row;gap:7px;justify-content:space-between}[data-monster-role=filter],[data-monster-role=popper-filter]{display:flex;flex-grow:200;order:99999999;visibility:hidden}[data-monster-role=filter].active{background-color:var(--monster-bg-color-primary-2);border:0;border-color:var(--monster-bg-color-primary-3);border-bottom:1px solid var(--monster-bg-color-primary-3);color:var(--monster-color-primary-2);min-width:40%;outline:none;visibility:visible}.active[data-monster-role=filter][name=popper-filter]{height:1.5em;margin:2.5em;padding:2px;width:calc(100% - var(--monster-border-width)*2)}.option-filter-control{align-items:center;background-color:var(--monster-bg-color-primary-2);display:flex;height:2.5em;margin:-1.1em -1.1em .3em}[data-monster-role=remove-badge]{background-color:var(--monster-bg-color-primary-2);height:16px;margin-left:5px;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");order:2}[data-monster-role=remove-badge],[data-monster-role=status-or-remove-badges]{-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:.8em;mask-size:.8em;min-height:16px;width:16px}[data-monster-role=status-or-remove-badges]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}.open[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/%3E%3C/svg%3E\")}.empty[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-dash-circle' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-dash-circle' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8'/%3E%3C/svg%3E\")}.clear[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E\")}.error[data-monster-role=status-or-remove-badges]{background-color:var(--monster-bg-color-error-1);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\")}@media (prefers-color-scheme:dark){.error[data-monster-role=status-or-remove-badges]{background-color:var(--monster-color-error-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16'/%3E%3Cpath d='M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z'/%3E%3C/svg%3E\")}}.loading[data-monster-role=status-or-remove-badges]{animation-duration:1s;animation-iteration-count:infinite;animation-name:activity;animation-timing-function:cubic-bezier(0,0,.2,1);background-color:var(--monster-bg-color-primary-4);-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='activity' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='activity' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3C/svg%3E\")}@keyframes activity{0%{transform:scale(1)}50%{transform:scale(.1)}to{transform:scale(1)}}[data-monster-role=options]{flex-direction:column;flex-grow:1;overflow-x:hidden;scrollbar-color:var(--monster-color-primary-1) var(--monster-bg-color-primary-1);scrollbar-gutter:stable;scrollbar-width:thin}[data-monster-role=option],[data-monster-role=options]{box-sizing:border-box;display:flex;max-width:100%;min-width:0;width:100%}[data-monster-role=option]{align-items:center;padding:6px 5px}[data-monster-role=option] label{justify-content:flex-start}[data-monster-role=option] label,[data-monster-role=option] label>div{align-items:center;display:flex;flex-direction:row;max-width:100%;min-width:0;width:100%}[data-monster-role=option] label>div{justify-content:space-between;outline:none}[part=option-label]{max-width:100%;min-width:0;overflow-wrap:anywhere;word-break:break-word}.selected{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=option][data-monster-filtered=true],[data-monster-role=option][data-monster-visibility=hidden]{display:none}[data-monster-role=option][data-monster-focused=true]{outline:1px dashed var(--monster-color-selection-2);outline-offset:-2px}@media (prefers-color-scheme:dark){[data-monster-role=option][data-monster-focused=true]{outline:1px dashed var(--monster-color-selection-4)}}[data-monster-role=filter]::-moz-placeholder{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=filter]::placeholder{background-color:var(--monster-bg-color-primary-2);color:var(--monster-color-primary-2)}[data-monster-role=option]>input:focus,[data-monster-role=option]>label:focus{outline:none}[data-monster-role=selection-messages]:empty:before,[data-monster-role=summary-messages]:empty:before{content:\"\u00A0\"}.in-button-bar{border-color:var(--monster-bg-color-primary-4)!important;border-style:var(--monster-border-style)!important;border-width:var(--monster-border-width)!important}[data-monster-role=pagination]::part(nav){justify-content:flex-start}[data-monster-role=pagination]::part(list){margin-bottom:0;margin-top:0}
28
28
  }`, 0);
29
29
  } catch (e) {
30
30
  addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
@@ -375,7 +375,8 @@ function applyAdaptiveFloatingContentSize(floatingElement, maxHeight) {
375
375
  return;
376
376
  }
377
377
 
378
- if (contentElement.dataset.monsterOverflowMode === "visible") {
378
+ const overflowMode = contentElement.dataset.monsterOverflowMode;
379
+ if (overflowMode === "visible") {
379
380
  return;
380
381
  }
381
382
 
@@ -392,6 +393,20 @@ function applyAdaptiveFloatingContentSize(floatingElement, maxHeight) {
392
393
  Number.isFinite(contentMaxHeight) && contentMaxHeight > 0
393
394
  ? Math.max(contentMaxHeight, minimumReadableHeight)
394
395
  : contentMaxHeight;
396
+ const preferredContentHeight = getRequiredContentHeight(contentElement);
397
+
398
+ if (overflowMode === "horizontal" || overflowMode === "both") {
399
+ // Overlay-aware modes keep the parent wrapper sized to the real inline content.
400
+ // Nested poppers may still escape, but they must not inflate the outer popper height.
401
+ applyOverlayAwareContentHeight(
402
+ contentElement,
403
+ preferredContentHeight,
404
+ nextContentMaxHeight,
405
+ minimumReadableHeight,
406
+ );
407
+ syncNestedScrollContainerHeight(contentElement, nextContentMaxHeight);
408
+ return;
409
+ }
395
410
 
396
411
  if (Number.isFinite(nextContentMaxHeight) && nextContentMaxHeight > 0) {
397
412
  contentElement.style.maxHeight = `${nextContentMaxHeight}px`;
@@ -402,6 +417,39 @@ function applyAdaptiveFloatingContentSize(floatingElement, maxHeight) {
402
417
  syncNestedScrollContainerHeight(contentElement, nextContentMaxHeight);
403
418
  }
404
419
 
420
+ function applyOverlayAwareContentHeight(
421
+ contentElement,
422
+ preferredContentHeight,
423
+ contentMaxHeight,
424
+ minimumReadableHeight,
425
+ ) {
426
+ const preferredHeight =
427
+ Number.isFinite(preferredContentHeight) && preferredContentHeight > 0
428
+ ? Math.max(preferredContentHeight, minimumReadableHeight)
429
+ : minimumReadableHeight;
430
+ const constrainedHeight =
431
+ Number.isFinite(contentMaxHeight) && contentMaxHeight > 0
432
+ ? Math.min(preferredHeight, contentMaxHeight)
433
+ : preferredHeight;
434
+ const isConstrained =
435
+ Number.isFinite(contentMaxHeight) &&
436
+ contentMaxHeight > 0 &&
437
+ preferredHeight > contentMaxHeight;
438
+
439
+ contentElement.style.removeProperty("overflow");
440
+ contentElement.style.overflowX = "visible";
441
+ contentElement.style.overflowY = isConstrained ? "auto" : "visible";
442
+
443
+ if (Number.isFinite(constrainedHeight) && constrainedHeight > 0) {
444
+ contentElement.style.height = `${constrainedHeight}px`;
445
+ contentElement.style.maxHeight = `${constrainedHeight}px`;
446
+ return;
447
+ }
448
+
449
+ contentElement.style.removeProperty("height");
450
+ contentElement.style.removeProperty("maxHeight");
451
+ }
452
+
405
453
  function getFloatingContentElement(floatingElement) {
406
454
  for (const child of floatingElement.children) {
407
455
  if (!(child instanceof HTMLElement)) {
@@ -628,7 +676,11 @@ function resetAdaptiveFloatingElementSize(floatingElement) {
628
676
  return;
629
677
  }
630
678
 
679
+ contentElement.style.removeProperty("height");
631
680
  contentElement.style.removeProperty("maxHeight");
681
+ contentElement.style.removeProperty("overflow");
682
+ contentElement.style.removeProperty("overflowX");
683
+ contentElement.style.removeProperty("overflowY");
632
684
 
633
685
  const nestedScrollableElement = getNestedScrollableElement(contentElement);
634
686
  if (!(nestedScrollableElement instanceof HTMLElement)) {
@@ -659,6 +711,22 @@ function getRequiredContentWidth(contentElement) {
659
711
  return Math.max(contentElement.scrollWidth, contentElement.clientWidth);
660
712
  }
661
713
 
714
+ function getRequiredContentHeight(contentElement) {
715
+ const nestedScrollableElement = getNestedScrollableElement(contentElement);
716
+ if (nestedScrollableElement instanceof HTMLElement) {
717
+ const contentRect = contentElement.getBoundingClientRect();
718
+ const nestedRect = nestedScrollableElement.getBoundingClientRect();
719
+ const reservedHeight = Math.max(0, contentRect.height - nestedRect.height);
720
+ return Math.max(
721
+ contentElement.scrollHeight,
722
+ nestedScrollableElement.scrollHeight + reservedHeight,
723
+ contentElement.clientHeight,
724
+ );
725
+ }
726
+
727
+ return Math.max(contentElement.scrollHeight, contentElement.clientHeight);
728
+ }
729
+
662
730
  function getNestedScrollableElement(contentElement) {
663
731
  for (const child of contentElement.children) {
664
732
  if (!(child instanceof HTMLElement)) {
@@ -293,6 +293,8 @@ class Popper extends CustomElement {
293
293
  /**
294
294
  * Resolves the effective content overflow mode for the rendered wrapper.
295
295
  * Subclasses can override this when the configured option is only an intermediate mode.
296
+ * `smart` keeps regular content measurable inside the popper while nested overlays
297
+ * are allowed to escape horizontally without forcing the parent wrapper to size to them.
296
298
  *
297
299
  * @return {string}
298
300
  */
@@ -742,10 +744,27 @@ function applyContentOverflowMode() {
742
744
  return;
743
745
  }
744
746
 
745
- contentElement.setAttribute(
746
- "data-monster-overflow-mode",
747
- this.resolveContentOverflowMode(),
748
- );
747
+ const overflowMode = this.resolveContentOverflowMode();
748
+ contentElement.setAttribute("data-monster-overflow-mode", overflowMode);
749
+
750
+ switch (overflowMode) {
751
+ case "horizontal":
752
+ contentElement.style.overflow = "visible";
753
+ contentElement.style.removeProperty("max-height");
754
+ contentElement.style.removeProperty("max-width");
755
+ break;
756
+ case "both":
757
+ case "visible":
758
+ contentElement.style.overflow = "visible";
759
+ contentElement.style.maxHeight = "none";
760
+ contentElement.style.maxWidth = "none";
761
+ break;
762
+ default:
763
+ contentElement.style.removeProperty("overflow");
764
+ contentElement.style.removeProperty("max-height");
765
+ contentElement.style.removeProperty("max-width");
766
+ break;
767
+ }
749
768
  }
750
769
 
751
770
  /**
@@ -33,7 +33,49 @@ let html2 = `
33
33
  </div>
34
34
  `;
35
35
 
36
+ function createJsonResponse(data, status = 200) {
37
+ let headers = new Map();
38
+ headers.set('content-type', 'application/json');
39
+
40
+ return Promise.resolve({
41
+ ok: status >= 200 && status < 300,
42
+ status,
43
+ headers,
44
+ text: function () {
45
+ return Promise.resolve(JSON.stringify(data));
46
+ }
47
+ });
48
+ }
49
+
50
+ function waitForCondition(check, {timeout = 4000, interval = 25} = {}) {
51
+ return new Promise((resolve, reject) => {
52
+ const start = Date.now();
53
+
54
+ const poll = () => {
55
+ try {
56
+ if (check()) {
57
+ resolve();
58
+ return;
59
+ }
60
+ } catch (e) {
61
+ reject(e);
62
+ return;
63
+ }
64
+
65
+ if (Date.now() - start >= timeout) {
66
+ reject(new Error('Timed out while waiting for test condition.'));
67
+ return;
68
+ }
69
+
70
+ setTimeout(poll, interval);
71
+ };
72
+
73
+ poll();
74
+ });
75
+ }
76
+
36
77
  let Select,
78
+ SelectStyleSheet,
37
79
  getDefaultSelectPopperPositionProfile,
38
80
  resolveSelectListDimension,
39
81
  resolveSelectPopperWidthConstraints,
@@ -61,6 +103,9 @@ describe('Select', function () {
61
103
  resolveSelectPopperWidthConstraints = m['resolveSelectPopperWidthConstraints'];
62
104
  resolveSelectVisibleRect = m['resolveSelectVisibleRect'];
63
105
  resolveSelectViewportMetrics = m['resolveSelectViewportMetrics'];
106
+ return import("../../../../source/components/form/stylesheet/select.mjs");
107
+ }).then((m) => {
108
+ SelectStyleSheet = m['SelectStyleSheet'];
64
109
  done()
65
110
  }).catch(e => done(e))
66
111
 
@@ -197,6 +242,8 @@ describe('Select', function () {
197
242
  });
198
243
 
199
244
  describe('Popper sizing', function () {
245
+ this.timeout(5000);
246
+
200
247
  afterEach(() => {
201
248
  let mocks = document.getElementById('mocks');
202
249
  mocks.innerHTML = "";
@@ -260,6 +307,16 @@ describe('Select', function () {
260
307
  expect(result.overflowY).to.equal('hidden');
261
308
  });
262
309
 
310
+ it('should keep option list scroll layout stable while overflow toggles', function () {
311
+ const cssText = Array.from(SelectStyleSheet.cssRules)
312
+ .map((rule) => rule.cssText)
313
+ .join('\n')
314
+ .replace(/\s+/g, '');
315
+
316
+ expect(cssText).to.contain('scrollbar-gutter:stable');
317
+ expect(cssText).to.not.contain('transition:height');
318
+ });
319
+
263
320
  it('should refresh the content max height when the available popper height grows again', function (done) {
264
321
  const mocks = document.getElementById('mocks');
265
322
  const select = document.createElement('monster-select');
@@ -722,25 +779,251 @@ describe('Select', function () {
722
779
 
723
780
  setTimeout(() => {
724
781
  try {
725
- const observer = mockIntersectionObserver.getInstance();
726
- observer.enterNode();
782
+ expect(lookupCount).to.equal(0);
727
783
  } catch (e) {
728
784
  mockIntersectionObserver.restore();
729
785
  return done(e);
730
786
  }
731
787
 
788
+ mockIntersectionObserver.restore();
789
+ done();
790
+ }, 150);
791
+ });
792
+
793
+ it('should not refetch after selecting an already loaded remote option', function (done) {
794
+ this.timeout(3000);
795
+
796
+ let mocks = document.getElementById('mocks');
797
+ const requests = [];
798
+
799
+ global['fetch'] = function (url) {
800
+ requests.push(String(url));
801
+ return createJsonResponse({
802
+ items: [
803
+ {id: 'alpha', name: 'Alpha'}
804
+ ],
805
+ pagination: {
806
+ total: 1,
807
+ page: 1,
808
+ perPage: 1
809
+ }
810
+ });
811
+ };
812
+
813
+ const select = document.createElement('monster-select');
814
+ select.setOption('url', 'https://example.com/items?filter={filter}&page={page}');
815
+ select.setOption('filter.mode', 'remote');
816
+ select.setOption('filter.defaultValue', '*');
817
+ select.setOption('mapping.selector', 'items.*');
818
+ select.setOption('mapping.labelTemplate', '${name}');
819
+ select.setOption('mapping.valueTemplate', '${id}');
820
+ select.setOption('mapping.total', 'pagination.total');
821
+ select.setOption('mapping.currentPage', 'pagination.page');
822
+ select.setOption('mapping.objectsPerPage', 'pagination.perPage');
823
+ mocks.appendChild(select);
824
+
825
+ setTimeout(() => {
826
+ select.fetch('https://example.com/items?filter=*&page=1')
827
+ .then(() => {
828
+ try {
829
+ expect(requests).to.deep.equal([
830
+ 'https://example.com/items?filter=*&page=1'
831
+ ]);
832
+
833
+ select.value = 'alpha';
834
+ } catch (e) {
835
+ return done(e);
836
+ }
837
+
838
+ setTimeout(() => {
839
+ try {
840
+ expect(requests).to.deep.equal([
841
+ 'https://example.com/items?filter=*&page=1'
842
+ ]);
843
+ } catch (e) {
844
+ return done(e);
845
+ }
846
+
847
+ done();
848
+ }, 200);
849
+ })
850
+ .catch((e) => done(e));
851
+ }, 50);
852
+ });
853
+
854
+ it('should reuse defaultOptionsUrl after clearing the filter and reopening', async function () {
855
+ this.timeout(5000);
856
+
857
+ let mocks = document.getElementById('mocks');
858
+ const requests = [];
859
+
860
+ global['fetch'] = function (url) {
861
+ const requestUrl = String(url);
862
+ requests.push(requestUrl);
863
+
864
+ if (requestUrl.indexOf('/defaults') !== -1) {
865
+ return createJsonResponse({
866
+ items: [
867
+ {id: 'seed', name: 'Seed'}
868
+ ],
869
+ pagination: {
870
+ total: 1,
871
+ page: 1,
872
+ perPage: 1
873
+ }
874
+ });
875
+ }
876
+
877
+ return createJsonResponse({
878
+ items: [
879
+ {id: 'match', name: 'Match'}
880
+ ],
881
+ pagination: {
882
+ total: 1,
883
+ page: 1,
884
+ perPage: 1
885
+ }
886
+ });
887
+ };
888
+
889
+ const select = document.createElement('monster-select');
890
+ select.setOption('url', 'https://example.com/items?filter={filter}&page={page}');
891
+ select.setOption('filter.mode', 'remote');
892
+ select.setOption('filter.position', 'popper');
893
+ select.setOption('filter.defaultOptionsUrl', 'https://example.com/defaults?page={page}');
894
+ select.setOption('mapping.selector', 'items.*');
895
+ select.setOption('mapping.labelTemplate', '${name}');
896
+ select.setOption('mapping.valueTemplate', '${id}');
897
+ select.setOption('mapping.total', 'pagination.total');
898
+ select.setOption('mapping.currentPage', 'pagination.page');
899
+ select.setOption('mapping.objectsPerPage', 'pagination.perPage');
900
+ mocks.appendChild(select);
901
+
902
+ const dispatchFilterKey = (input, code, key) => {
903
+ input.dispatchEvent(new KeyboardEvent('keydown', {
904
+ bubbles: true,
905
+ composed: true,
906
+ code,
907
+ key
908
+ }));
909
+ };
910
+
911
+ await waitForCondition(() => {
912
+ return select.shadowRoot.querySelector('[data-monster-role=container]') instanceof HTMLElement;
913
+ });
914
+
915
+ const container = select.shadowRoot.querySelector('[data-monster-role=container]');
916
+ const filterInput = select.shadowRoot.querySelector('[data-monster-role=filter][name="popper-filter"]');
917
+
918
+ container.click();
919
+ await waitForCondition(() => requests.length >= 1);
920
+ expect(requests[0]).to.equal('https://example.com/defaults?page=1');
921
+
922
+ filterInput.value = 'alpha';
923
+ dispatchFilterKey(filterInput, 'KeyA', 'a');
924
+ await waitForCondition(() => requests.length >= 2);
925
+ expect(requests[1]).to.equal('https://example.com/items?filter=alpha&page=1');
926
+
927
+ filterInput.value = '';
928
+ dispatchFilterKey(filterInput, 'Backspace', 'Backspace');
929
+ await waitForCondition(() => requests.length >= 3);
930
+ expect(requests[2]).to.equal('https://example.com/defaults?page=1');
931
+
932
+ container.click();
933
+ await waitForCondition(() => select.shadowRoot.querySelector('[data-monster-role=popper]').style.display === 'none');
934
+
935
+ container.click();
936
+ await waitForCondition(() => requests.length >= 4);
937
+ expect(requests[3]).to.equal('https://example.com/defaults?page=1');
938
+ });
939
+
940
+ it('should keep unresolved lookup values visible and mark their badge', function (done) {
941
+ this.timeout(3000);
942
+
943
+ let mocks = document.getElementById('mocks');
944
+ global['fetch'] = function () {
945
+ return createJsonResponse({
946
+ items: [],
947
+ pagination: {
948
+ total: 0,
949
+ page: 1,
950
+ perPage: 1
951
+ }
952
+ });
953
+ };
954
+
955
+ const select = document.createElement('monster-select');
956
+ select.setOption('lookup.url', 'https://example.com/items?filter={filter}');
957
+ select.setOption('mapping.selector', 'items.*');
958
+ select.setOption('mapping.labelTemplate', '${name}');
959
+ select.setOption('mapping.valueTemplate', '${id}');
960
+ select.setOption('selection', [{value: 'missing-key'}]);
961
+ mocks.appendChild(select);
962
+
963
+ setTimeout(() => {
964
+ try {
965
+ const badge = select.shadowRoot.querySelector('[data-monster-role=badge]');
966
+ const badgeLabel = select.shadowRoot.querySelector('[data-monster-role=badge-label]');
967
+
968
+ expect(badge).to.be.instanceof(HTMLDivElement);
969
+ expect(badgeLabel).to.be.instanceof(HTMLDivElement);
970
+ expect(badgeLabel.textContent.trim()).to.equal('missing-key');
971
+ expect(badge.className).to.contain('monster-badge-warning');
972
+ expect(badge.className).to.not.contain('monster-badge-primary');
973
+ expect(badge.getAttribute('data-monster-unresolved')).to.equal('true');
974
+ expect(badgeLabel.textContent).to.not.contain(select.getOption('labels.cannot-be-loaded'));
975
+ } catch (e) {
976
+ return done(e);
977
+ }
978
+
979
+ done();
980
+ }, 250);
981
+ });
982
+
983
+ it('should clear the unresolved badge state once a local option can resolve the value', function (done) {
984
+ this.timeout(4000);
985
+
986
+ let mocks = document.getElementById('mocks');
987
+ global['fetch'] = function () {
988
+ return createJsonResponse({
989
+ items: [],
990
+ pagination: {
991
+ total: 0,
992
+ page: 1,
993
+ perPage: 1
994
+ }
995
+ });
996
+ };
997
+
998
+ const select = document.createElement('monster-select');
999
+ select.setOption('lookup.url', 'https://example.com/items?filter={filter}');
1000
+ select.setOption('mapping.selector', 'items.*');
1001
+ select.setOption('mapping.labelTemplate', '${name}');
1002
+ select.setOption('mapping.valueTemplate', '${id}');
1003
+ select.setOption('selection', [{value: 'missing-key'}]);
1004
+ mocks.appendChild(select);
1005
+
1006
+ setTimeout(() => {
1007
+ select.setOption('options', [{label: 'Resolved Label', value: 'missing-key'}]);
1008
+ select.value = 'missing-key';
1009
+
732
1010
  setTimeout(() => {
733
1011
  try {
734
- expect(lookupCount).to.equal(0);
1012
+ const badge = select.shadowRoot.querySelector('[data-monster-role=badge]');
1013
+ const badgeLabel = select.shadowRoot.querySelector('[data-monster-role=badge-label]');
1014
+
1015
+ expect(badge).to.be.instanceof(HTMLDivElement);
1016
+ expect(badgeLabel.textContent.trim()).to.equal('Resolved Label');
1017
+ expect(badge.className).to.contain('monster-badge-primary');
1018
+ expect(badge.className).to.not.contain('monster-badge-warning');
1019
+ expect(badge.getAttribute('data-monster-unresolved')).to.not.equal('true');
735
1020
  } catch (e) {
736
- mockIntersectionObserver.restore();
737
1021
  return done(e);
738
1022
  }
739
1023
 
740
- mockIntersectionObserver.restore();
741
1024
  done();
742
1025
  }, 150);
743
- }, 50);
1026
+ }, 250);
744
1027
  });
745
1028
 
746
1029
  it('should not throw when IntersectionObserver is unavailable', function (done) {