govuk_publishing_components 65.1.0 → 65.2.0

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/component_guide/application.scss +13 -15
  3. data/app/assets/stylesheets/govuk_publishing_components/all-components.scss +0 -1
  4. data/app/assets/stylesheets/govuk_publishing_components/components/_contents-list.scss +25 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/components/_details.scss +34 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_heading.scss +1 -0
  7. data/app/assets/stylesheets/govuk_publishing_components/components/helpers/_markdown-typography.scss +4 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/specific-components.scss +0 -1
  9. data/app/controllers/govuk_publishing_components/applications_page_controller.rb +1 -1
  10. data/app/controllers/govuk_publishing_components/audit_controller.rb +0 -1
  11. data/app/models/govuk_publishing_components/component_doc.rb +10 -3
  12. data/app/models/govuk_publishing_components/component_wrapper_helper_options.rb +4 -2
  13. data/app/views/govuk_publishing_components/component_guide/component_doc/_component.html.erb +1 -1
  14. data/app/views/govuk_publishing_components/component_guide/component_doc/_preview.html.erb +2 -2
  15. data/app/views/govuk_publishing_components/component_guide/show.html.erb +47 -33
  16. data/app/views/govuk_publishing_components/components/_details.html.erb +4 -0
  17. data/app/views/govuk_publishing_components/components/_devolved_nations.html.erb +2 -2
  18. data/app/views/govuk_publishing_components/components/_option_select.html.erb +2 -2
  19. data/app/views/govuk_publishing_components/components/docs/details.yml +16 -0
  20. data/lib/govuk_publishing_components/presenters/devolved_nations_helper.rb +13 -7
  21. data/lib/govuk_publishing_components/version.rb +1 -1
  22. data/node_modules/choices.js/README.md +140 -30
  23. data/node_modules/choices.js/package.json +10 -13
  24. data/node_modules/choices.js/public/assets/scripts/choices.js +144 -89
  25. data/node_modules/choices.js/public/assets/scripts/choices.min.js +2 -2
  26. data/node_modules/choices.js/public/assets/scripts/choices.mjs +144 -89
  27. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.js +144 -86
  28. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.min.js +2 -2
  29. data/node_modules/choices.js/public/assets/scripts/choices.search-basic.mjs +144 -86
  30. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.js +139 -77
  31. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.min.js +2 -2
  32. data/node_modules/choices.js/public/assets/scripts/choices.search-kmp.mjs +139 -77
  33. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.js +137 -76
  34. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.min.js +2 -2
  35. data/node_modules/choices.js/public/assets/scripts/choices.search-prefix.mjs +137 -76
  36. data/node_modules/choices.js/public/assets/styles/base.css +39 -9
  37. data/node_modules/choices.js/public/assets/styles/base.css.map +1 -1
  38. data/node_modules/choices.js/public/assets/styles/base.min.css +1 -1
  39. data/node_modules/choices.js/public/assets/styles/choices.css +93 -95
  40. data/node_modules/choices.js/public/assets/styles/choices.css.map +1 -1
  41. data/node_modules/choices.js/public/assets/styles/choices.min.css +1 -1
  42. data/node_modules/choices.js/public/types/src/scripts/choices.d.ts +11 -0
  43. data/node_modules/choices.js/public/types/src/scripts/components/container.d.ts +2 -0
  44. data/node_modules/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts +2 -1
  45. data/node_modules/choices.js/public/types/src/scripts/interfaces/class-names.d.ts +2 -0
  46. data/node_modules/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts +2 -1
  47. data/node_modules/choices.js/public/types/src/scripts/interfaces/options.d.ts +19 -3
  48. data/node_modules/choices.js/public/types/src/scripts/interfaces/store.d.ts +2 -1
  49. data/node_modules/choices.js/public/types/src/scripts/interfaces/types.d.ts +2 -1
  50. data/node_modules/choices.js/public/types/src/scripts/lib/utils.d.ts +3 -1
  51. data/node_modules/choices.js/src/scripts/choices.ts +110 -64
  52. data/node_modules/choices.js/src/scripts/components/container.ts +8 -0
  53. data/node_modules/choices.js/src/scripts/components/wrapped-select.ts +3 -1
  54. data/node_modules/choices.js/src/scripts/defaults.ts +12 -7
  55. data/node_modules/choices.js/src/scripts/interfaces/choice-full.ts +2 -1
  56. data/node_modules/choices.js/src/scripts/interfaces/class-names.ts +2 -0
  57. data/node_modules/choices.js/src/scripts/interfaces/event-choice.ts +1 -0
  58. data/node_modules/choices.js/src/scripts/interfaces/input-choice.ts +4 -2
  59. data/node_modules/choices.js/src/scripts/interfaces/options.ts +21 -3
  60. data/node_modules/choices.js/src/scripts/interfaces/store.ts +2 -1
  61. data/node_modules/choices.js/src/scripts/interfaces/types.ts +3 -1
  62. data/node_modules/choices.js/src/scripts/lib/utils.ts +27 -4
  63. data/node_modules/choices.js/src/scripts/search/kmp.ts +2 -1
  64. data/node_modules/choices.js/src/scripts/store/store.ts +4 -1
  65. data/node_modules/choices.js/src/scripts/templates.ts +6 -3
  66. data/node_modules/choices.js/src/styles/base.scss +42 -9
  67. data/node_modules/choices.js/src/styles/choices.scss +119 -93
  68. metadata +2 -3
  69. data/app/assets/stylesheets/govuk_publishing_components/components/helpers/_contents-list-helper.scss +0 -24
@@ -1,4 +1,4 @@
1
- /*! choices.js v11.1.0 | © 2025 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
1
+ /*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */
2
2
 
3
3
  /******************************************************************************
4
4
  Copyright (c) Microsoft Corporation.
@@ -202,9 +202,6 @@ var strToEl = (function () {
202
202
  return firstChild;
203
203
  };
204
204
  })();
205
- var resolveNoticeFunction = function (fn, value) {
206
- return typeof fn === 'function' ? fn(sanitise(value), value) : fn;
207
- };
208
205
  var resolveStringFunction = function (fn) {
209
206
  return typeof fn === 'function' ? fn() : fn;
210
207
  };
@@ -236,6 +233,26 @@ var unwrapStringForEscaped = function (s) {
236
233
  }
237
234
  return '';
238
235
  };
236
+ var getChoiceForOutput = function (choice, keyCode) {
237
+ return {
238
+ id: choice.id,
239
+ highlighted: choice.highlighted,
240
+ labelClass: choice.labelClass,
241
+ labelDescription: unwrapStringForRaw(choice.labelDescription),
242
+ customProperties: choice.customProperties,
243
+ disabled: choice.disabled,
244
+ active: choice.active,
245
+ label: choice.label,
246
+ placeholder: choice.placeholder,
247
+ value: choice.value,
248
+ groupValue: choice.group ? choice.group.label : undefined,
249
+ element: choice.element,
250
+ keyCode: keyCode,
251
+ };
252
+ };
253
+ var resolveNoticeFunction = function (fn, value, item) {
254
+ return typeof fn === 'function' ? fn(sanitise(value), unwrapStringForRaw(value), item) : fn;
255
+ };
239
256
  var escapeForTemplate = function (allowHTML, s) {
240
257
  return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);
241
258
  };
@@ -403,6 +420,12 @@ var Container = /** @class */ (function () {
403
420
  Container.prototype.removeFocusState = function () {
404
421
  removeClassesFromElement(this.element, this.classNames.focusState);
405
422
  };
423
+ Container.prototype.addInvalidState = function () {
424
+ addClassesToElement(this.element, this.classNames.invalidState);
425
+ };
426
+ Container.prototype.removeInvalidState = function () {
427
+ removeClassesFromElement(this.element, this.classNames.invalidState);
428
+ };
406
429
  Container.prototype.enable = function () {
407
430
  removeClassesFromElement(this.element, this.classNames.disabledState);
408
431
  this.element.removeAttribute('aria-disabled');
@@ -868,7 +891,9 @@ var WrappedSelect = /** @class */ (function (_super) {
868
891
  highlighted: false,
869
892
  placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),
870
893
  labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,
871
- labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined,
894
+ labelDescription: typeof option.dataset.labelDescription !== 'undefined'
895
+ ? { trusted: option.dataset.labelDescription }
896
+ : undefined,
872
897
  customProperties: parseCustomProperties(option.dataset.customProperties),
873
898
  };
874
899
  };
@@ -914,6 +939,7 @@ var DEFAULT_CLASSNAMES = {
914
939
  selectedState: ['is-selected'],
915
940
  flippedState: ['is-flipped'],
916
941
  loadingState: ['is-loading'],
942
+ invalidState: ['is-invalid'],
917
943
  notice: ['choices__notice'],
918
944
  addChoice: ['choices__item--selectable', 'add-choice'],
919
945
  noResults: ['has-no-results'],
@@ -941,6 +967,7 @@ var DEFAULT_CONFIG = {
941
967
  paste: true,
942
968
  searchEnabled: true,
943
969
  searchChoices: true,
970
+ searchDisabledChoices: false,
944
971
  searchFloor: 1,
945
972
  searchResultLimit: 4,
946
973
  searchFields: ['label', 'value'],
@@ -956,6 +983,7 @@ var DEFAULT_CONFIG = {
956
983
  prependValue: null,
957
984
  appendValue: null,
958
985
  renderSelectedChoices: 'auto',
986
+ searchRenderSelectedChoices: true,
959
987
  loadingText: 'Loading...',
960
988
  noResultsText: 'No results found',
961
989
  noChoicesText: 'No choices to choose from',
@@ -964,7 +992,9 @@ var DEFAULT_CONFIG = {
964
992
  customAddItemText: 'Only values matching specific conditions can be added',
965
993
  addItemText: function (value) { return "Press Enter to add <b>\"".concat(value, "\"</b>"); },
966
994
  removeItemIconText: function () { return "Remove item"; },
967
- removeItemLabelText: function (value) { return "Remove item: ".concat(value); },
995
+ removeItemLabelText: function (value, _valueRaw, i) {
996
+ return "Remove item: ".concat(i ? sanitise(i.label) : value);
997
+ },
968
998
  maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); },
969
999
  valueComparer: function (value1, value2) { return value1 === value2; },
970
1000
  fuseOptions: {
@@ -1265,7 +1295,8 @@ var Store = /** @class */ (function () {
1265
1295
  * Get choices that can be searched (excluding placeholders or disabled choices)
1266
1296
  */
1267
1297
  get: function () {
1268
- return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; });
1298
+ var context = this._context;
1299
+ return this.choices.filter(function (choice) { return !choice.placeholder && (context.searchDisabledChoices || !choice.disabled); });
1269
1300
  },
1270
1301
  enumerable: false,
1271
1302
  configurable: true
@@ -1379,11 +1410,12 @@ var SearchByKMP = /** @class */ (function () {
1379
1410
  var field = this._fields[k];
1380
1411
  if (field in obj && kmpSearch(needle, obj[field].toLowerCase()) !== -1) {
1381
1412
  results.push({
1382
- item: obj[field],
1413
+ item: obj,
1383
1414
  score: count,
1384
1415
  rank: count + 1,
1385
1416
  });
1386
1417
  count++;
1418
+ break;
1387
1419
  }
1388
1420
  }
1389
1421
  }
@@ -1419,7 +1451,7 @@ var assignCustomProperties = function (el, choice, withCustomProperties) {
1419
1451
  dataset.labelClass = getClassNames(labelClass).join(' ');
1420
1452
  }
1421
1453
  if (labelDescription) {
1422
- dataset.labelDescription = labelDescription;
1454
+ dataset.labelDescription = unwrapStringForRaw(labelDescription);
1423
1455
  }
1424
1456
  if (withCustomProperties && customProperties) {
1425
1457
  if (typeof customProperties === 'string') {
@@ -1526,8 +1558,9 @@ var templates = {
1526
1558
  var removeButton = document.createElement('button');
1527
1559
  removeButton.type = 'button';
1528
1560
  addClassesToElement(removeButton, button);
1529
- setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));
1530
- var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);
1561
+ var eventChoice = getChoiceForOutput(choice);
1562
+ setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value, eventChoice));
1563
+ var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value, eventChoice);
1531
1564
  if (REMOVE_ITEM_LABEL) {
1532
1565
  removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);
1533
1566
  }
@@ -1632,6 +1665,7 @@ var templates = {
1632
1665
  else {
1633
1666
  addClassesToElement(div, itemSelectable);
1634
1667
  div.dataset.choiceSelectable = '';
1668
+ div.setAttribute('aria-selected', choice.selected ? 'true' : 'false');
1635
1669
  }
1636
1670
  return div;
1637
1671
  },
@@ -1801,7 +1835,7 @@ var Choices = /** @class */ (function () {
1801
1835
  this.initialised = false;
1802
1836
  this._store = new Store(config);
1803
1837
  this._currentValue = '';
1804
- config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;
1838
+ config.searchEnabled = !isText && config.searchEnabled;
1805
1839
  this._canSearch = config.searchEnabled;
1806
1840
  this._isScrollingOnIe = false;
1807
1841
  this._highlightPosition = 0;
@@ -1841,6 +1875,8 @@ var Choices = /** @class */ (function () {
1841
1875
  this._onEscapeKey = this._onEscapeKey.bind(this);
1842
1876
  this._onDirectionKey = this._onDirectionKey.bind(this);
1843
1877
  this._onDeleteKey = this._onDeleteKey.bind(this);
1878
+ this._onChange = this._onChange.bind(this);
1879
+ this._onInvalid = this._onInvalid.bind(this);
1844
1880
  // If element has already been initialised with Choices, fail silently
1845
1881
  if (this.passedElement.isActive) {
1846
1882
  if (!config.silent) {
@@ -1947,7 +1983,7 @@ var Choices = /** @class */ (function () {
1947
1983
  }
1948
1984
  this._store.dispatch(highlightItem(choice, true));
1949
1985
  if (runEvent) {
1950
- this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));
1986
+ this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(choice));
1951
1987
  }
1952
1988
  return this;
1953
1989
  };
@@ -1962,7 +1998,7 @@ var Choices = /** @class */ (function () {
1962
1998
  }
1963
1999
  this._store.dispatch(highlightItem(choice, false));
1964
2000
  if (runEvent) {
1965
- this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));
2001
+ this.passedElement.triggerEvent(EventType.unhighlightItem, getChoiceForOutput(choice));
1966
2002
  }
1967
2003
  return this;
1968
2004
  };
@@ -1972,7 +2008,7 @@ var Choices = /** @class */ (function () {
1972
2008
  _this._store.items.forEach(function (item) {
1973
2009
  if (!item.highlighted) {
1974
2010
  _this._store.dispatch(highlightItem(item, true));
1975
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
2011
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1976
2012
  }
1977
2013
  });
1978
2014
  });
@@ -1984,7 +2020,7 @@ var Choices = /** @class */ (function () {
1984
2020
  _this._store.items.forEach(function (item) {
1985
2021
  if (item.highlighted) {
1986
2022
  _this._store.dispatch(highlightItem(item, false));
1987
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
2023
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1988
2024
  }
1989
2025
  });
1990
2026
  });
@@ -2039,6 +2075,11 @@ var Choices = /** @class */ (function () {
2039
2075
  _this.input.focus();
2040
2076
  }
2041
2077
  _this.passedElement.triggerEvent(EventType.showDropdown);
2078
+ var activeElement = _this.choiceList.element.querySelector(getClassNamesSelector(_this.config.classNames.selectedState));
2079
+ if (activeElement !== null && !isScrolledIntoView(activeElement, _this.choiceList.element)) {
2080
+ // We use the native scrollIntoView function instead of choiceList.scrollToChildElement to avoid animated scroll.
2081
+ activeElement.scrollIntoView();
2082
+ }
2042
2083
  });
2043
2084
  return this;
2044
2085
  };
@@ -2047,6 +2088,7 @@ var Choices = /** @class */ (function () {
2047
2088
  if (!this.dropdown.isActive) {
2048
2089
  return this;
2049
2090
  }
2091
+ this._removeHighlightedChoices();
2050
2092
  requestAnimationFrame(function () {
2051
2093
  _this.dropdown.hide();
2052
2094
  _this.containerOuter.close();
@@ -2059,9 +2101,8 @@ var Choices = /** @class */ (function () {
2059
2101
  return this;
2060
2102
  };
2061
2103
  Choices.prototype.getValue = function (valueOnly) {
2062
- var _this = this;
2063
2104
  var values = this._store.items.map(function (item) {
2064
- return (valueOnly ? item.value : _this._getChoiceForOutput(item));
2105
+ return (valueOnly ? item.value : getChoiceForOutput(item));
2065
2106
  });
2066
2107
  return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;
2067
2108
  };
@@ -2319,7 +2360,7 @@ var Choices = /** @class */ (function () {
2319
2360
  // @todo integrate with Store
2320
2361
  this._searcher.reset();
2321
2362
  if (choice.selected) {
2322
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));
2363
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(choice));
2323
2364
  }
2324
2365
  return this;
2325
2366
  };
@@ -2402,13 +2443,7 @@ var Choices = /** @class */ (function () {
2402
2443
  }
2403
2444
  var _a = this, config = _a.config, isSearching = _a._isSearching;
2404
2445
  var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;
2405
- var renderLimit = 0;
2406
- if (isSearching && config.searchResultLimit > 0) {
2407
- renderLimit = config.searchResultLimit;
2408
- }
2409
- else if (config.renderChoiceLimit > 0) {
2410
- renderLimit = config.renderChoiceLimit;
2411
- }
2446
+ var renderLimit = isSearching ? config.searchResultLimit : config.renderChoiceLimit;
2412
2447
  if (this._isSelectElement) {
2413
2448
  var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });
2414
2449
  if (backingOptions.length) {
@@ -2418,11 +2453,16 @@ var Choices = /** @class */ (function () {
2418
2453
  var fragment = document.createDocumentFragment();
2419
2454
  var renderableChoices = function (choices) {
2420
2455
  return choices.filter(function (choice) {
2421
- return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);
2456
+ return !choice.placeholder &&
2457
+ (isSearching
2458
+ ? (config.searchRenderSelectedChoices || !choice.selected) && !!choice.rank
2459
+ : config.renderSelectedChoices || !choice.selected);
2422
2460
  });
2423
2461
  };
2462
+ var showLabel = config.appendGroupInSearch && isSearching;
2424
2463
  var selectableChoices = false;
2425
- var renderChoices = function (choices, withinGroup, groupLabel) {
2464
+ var highlightedEl = null;
2465
+ var renderChoices = function (choices, withinGroup) {
2426
2466
  if (isSearching) {
2427
2467
  // sortByRank is used to ensure stable sorting, as scores are non-unique
2428
2468
  // this additionally ensures fuseOptions.sortFn is not ignored
@@ -2432,16 +2472,20 @@ var Choices = /** @class */ (function () {
2432
2472
  choices.sort(config.sorter);
2433
2473
  }
2434
2474
  var choiceLimit = choices.length;
2435
- choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2475
+ choiceLimit = !withinGroup && renderLimit > 0 && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2436
2476
  choiceLimit--;
2437
2477
  choices.every(function (choice, index) {
2438
2478
  // choiceEl being empty signals the contents has probably significantly changed
2439
- var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);
2479
+ var dropdownItem = choice.choiceEl ||
2480
+ _this._templates.choice(config, choice, config.itemSelectText, showLabel && choice.group ? choice.group.label : undefined);
2440
2481
  choice.choiceEl = dropdownItem;
2441
2482
  fragment.appendChild(dropdownItem);
2442
2483
  if (isSearching || !choice.selected) {
2443
2484
  selectableChoices = true;
2444
2485
  }
2486
+ else if (!highlightedEl) {
2487
+ highlightedEl = dropdownItem;
2488
+ }
2445
2489
  return index < choiceLimit;
2446
2490
  });
2447
2491
  };
@@ -2451,7 +2495,7 @@ var Choices = /** @class */ (function () {
2451
2495
  }
2452
2496
  if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {
2453
2497
  // If we have a placeholder choice along with groups
2454
- renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);
2498
+ renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false);
2455
2499
  }
2456
2500
  // If we have grouped options
2457
2501
  if (activeGroups.length && !isSearching) {
@@ -2460,7 +2504,7 @@ var Choices = /** @class */ (function () {
2460
2504
  }
2461
2505
  // render Choices without group first, regardless of sort, otherwise they won't be distinguishable
2462
2506
  // from the last group
2463
- renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);
2507
+ renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false);
2464
2508
  activeGroups.forEach(function (group) {
2465
2509
  var groupChoices = renderableChoices(group.choices);
2466
2510
  if (groupChoices.length) {
@@ -2470,12 +2514,12 @@ var Choices = /** @class */ (function () {
2470
2514
  dropdownGroup.remove();
2471
2515
  fragment.appendChild(dropdownGroup);
2472
2516
  }
2473
- renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);
2517
+ renderChoices(groupChoices, true);
2474
2518
  }
2475
2519
  });
2476
2520
  }
2477
2521
  else {
2478
- renderChoices(renderableChoices(activeChoices), false, undefined);
2522
+ renderChoices(renderableChoices(activeChoices), false);
2479
2523
  }
2480
2524
  }
2481
2525
  if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {
@@ -2489,9 +2533,7 @@ var Choices = /** @class */ (function () {
2489
2533
  }
2490
2534
  this._renderNotice(fragment);
2491
2535
  this.choiceList.element.replaceChildren(fragment);
2492
- if (selectableChoices) {
2493
- this._highlightChoice();
2494
- }
2536
+ this._highlightChoice(highlightedEl);
2495
2537
  };
2496
2538
  Choices.prototype._renderItems = function () {
2497
2539
  var _this = this;
@@ -2601,23 +2643,12 @@ var Choices = /** @class */ (function () {
2601
2643
  }
2602
2644
  }
2603
2645
  };
2646
+ /**
2647
+ * @deprecated Use utils.getChoiceForOutput
2648
+ */
2604
2649
  // eslint-disable-next-line class-methods-use-this
2605
2650
  Choices.prototype._getChoiceForOutput = function (choice, keyCode) {
2606
- return {
2607
- id: choice.id,
2608
- highlighted: choice.highlighted,
2609
- labelClass: choice.labelClass,
2610
- labelDescription: choice.labelDescription,
2611
- customProperties: choice.customProperties,
2612
- disabled: choice.disabled,
2613
- active: choice.active,
2614
- label: choice.label,
2615
- placeholder: choice.placeholder,
2616
- value: choice.value,
2617
- groupValue: choice.group ? choice.group.label : undefined,
2618
- element: choice.element,
2619
- keyCode: keyCode,
2620
- };
2651
+ return getChoiceForOutput(choice, keyCode);
2621
2652
  };
2622
2653
  Choices.prototype._triggerChange = function (value) {
2623
2654
  if (value === undefined || value === null) {
@@ -2633,7 +2664,7 @@ var Choices = /** @class */ (function () {
2633
2664
  if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {
2634
2665
  return;
2635
2666
  }
2636
- var id = element && parseDataSetId(element.parentElement);
2667
+ var id = element && parseDataSetId(element.closest('[data-id]'));
2637
2668
  var itemToRemove = id && items.find(function (item) { return item.id === id; });
2638
2669
  if (!itemToRemove) {
2639
2670
  return;
@@ -2822,7 +2853,7 @@ var Choices = /** @class */ (function () {
2822
2853
  var notice = '';
2823
2854
  if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {
2824
2855
  canAddItem = false;
2825
- notice = resolveNoticeFunction(config.customAddItemText, value);
2856
+ notice = resolveNoticeFunction(config.customAddItemText, value, undefined);
2826
2857
  }
2827
2858
  if (canAddItem) {
2828
2859
  var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });
@@ -2834,12 +2865,12 @@ var Choices = /** @class */ (function () {
2834
2865
  }
2835
2866
  if (!config.duplicateItemsAllowed) {
2836
2867
  canAddItem = false;
2837
- notice = resolveNoticeFunction(config.uniqueItemText, value);
2868
+ notice = resolveNoticeFunction(config.uniqueItemText, value, undefined);
2838
2869
  }
2839
2870
  }
2840
2871
  }
2841
2872
  if (canAddItem) {
2842
- notice = resolveNoticeFunction(config.addItemText, value);
2873
+ notice = resolveNoticeFunction(config.addItemText, value, undefined);
2843
2874
  }
2844
2875
  if (notice) {
2845
2876
  this._displayNotice(notice, NoticeTypes.addChoice);
@@ -2890,6 +2921,7 @@ var Choices = /** @class */ (function () {
2890
2921
  var documentElement = this._docRoot;
2891
2922
  var outerElement = this.containerOuter.element;
2892
2923
  var inputElement = this.input.element;
2924
+ var passedElement = this.passedElement.element;
2893
2925
  // capture events - can cancel event processing or propagation
2894
2926
  documentElement.addEventListener('touchend', this._onTouchEnd, true);
2895
2927
  outerElement.addEventListener('keydown', this._onKeyDown, true);
@@ -2927,12 +2959,21 @@ var Choices = /** @class */ (function () {
2927
2959
  passive: true,
2928
2960
  });
2929
2961
  }
2962
+ if (passedElement.hasAttribute('required')) {
2963
+ passedElement.addEventListener('change', this._onChange, {
2964
+ passive: true,
2965
+ });
2966
+ passedElement.addEventListener('invalid', this._onInvalid, {
2967
+ passive: true,
2968
+ });
2969
+ }
2930
2970
  this.input.addEventListeners();
2931
2971
  };
2932
2972
  Choices.prototype._removeEventListeners = function () {
2933
2973
  var documentElement = this._docRoot;
2934
2974
  var outerElement = this.containerOuter.element;
2935
2975
  var inputElement = this.input.element;
2976
+ var passedElement = this.passedElement.element;
2936
2977
  documentElement.removeEventListener('touchend', this._onTouchEnd, true);
2937
2978
  outerElement.removeEventListener('keydown', this._onKeyDown, true);
2938
2979
  outerElement.removeEventListener('mousedown', this._onMouseDown, true);
@@ -2950,6 +2991,10 @@ var Choices = /** @class */ (function () {
2950
2991
  if (inputElement.form) {
2951
2992
  inputElement.form.removeEventListener('reset', this._onFormReset);
2952
2993
  }
2994
+ if (passedElement.hasAttribute('required')) {
2995
+ passedElement.removeEventListener('change', this._onChange);
2996
+ passedElement.removeEventListener('invalid', this._onInvalid);
2997
+ }
2953
2998
  this.input.removeEventListeners();
2954
2999
  };
2955
3000
  Choices.prototype._onKeyDown = function (event) {
@@ -3199,7 +3244,7 @@ var Choices = /** @class */ (function () {
3199
3244
  */
3200
3245
  Choices.prototype._onMouseDown = function (event) {
3201
3246
  var target = event.target;
3202
- if (!(target instanceof HTMLElement)) {
3247
+ if (!(target instanceof Element)) {
3203
3248
  return;
3204
3249
  }
3205
3250
  // If we have our mouse down on the scrollbar and are on IE11...
@@ -3308,7 +3353,7 @@ var Choices = /** @class */ (function () {
3308
3353
  // Remove the focus state when the past outerContainer was the target
3309
3354
  containerOuter.removeFocusState();
3310
3355
  // Also close the dropdown if search is disabled
3311
- if (!this._canSearch) {
3356
+ if (!this.config.searchEnabled) {
3312
3357
  this.hideDropdown(true);
3313
3358
  }
3314
3359
  }
@@ -3332,13 +3377,19 @@ var Choices = /** @class */ (function () {
3332
3377
  }
3333
3378
  });
3334
3379
  };
3335
- Choices.prototype._highlightChoice = function (el) {
3336
- if (el === void 0) { el = null; }
3337
- var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3338
- if (!choices.length) {
3380
+ Choices.prototype._onChange = function (event) {
3381
+ if (!event.target.checkValidity()) {
3339
3382
  return;
3340
3383
  }
3341
- var passedEl = el;
3384
+ this.containerOuter.removeInvalidState();
3385
+ };
3386
+ Choices.prototype._onInvalid = function () {
3387
+ this.containerOuter.addInvalidState();
3388
+ };
3389
+ /**
3390
+ * Removes any highlighted choice options
3391
+ */
3392
+ Choices.prototype._removeHighlightedChoices = function () {
3342
3393
  var highlightedState = this.config.classNames.highlightedState;
3343
3394
  var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));
3344
3395
  // Remove any highlighted choices
@@ -3346,6 +3397,16 @@ var Choices = /** @class */ (function () {
3346
3397
  removeClassesFromElement(choice, highlightedState);
3347
3398
  choice.setAttribute('aria-selected', 'false');
3348
3399
  });
3400
+ };
3401
+ Choices.prototype._highlightChoice = function (el) {
3402
+ if (el === void 0) { el = null; }
3403
+ var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3404
+ if (!choices.length) {
3405
+ return;
3406
+ }
3407
+ var passedEl = el;
3408
+ var highlightedState = this.config.classNames.highlightedState;
3409
+ this._removeHighlightedChoices();
3349
3410
  if (passedEl) {
3350
3411
  this._highlightPosition = choices.indexOf(passedEl);
3351
3412
  }
@@ -3386,9 +3447,10 @@ var Choices = /** @class */ (function () {
3386
3447
  }
3387
3448
  this._store.dispatch(addItem(item));
3388
3449
  if (withEvents) {
3389
- this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));
3450
+ var eventChoice = getChoiceForOutput(item);
3451
+ this.passedElement.triggerEvent(EventType.addItem, eventChoice);
3390
3452
  if (userTriggered) {
3391
- this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));
3453
+ this.passedElement.triggerEvent(EventType.choice, eventChoice);
3392
3454
  }
3393
3455
  }
3394
3456
  };
@@ -3401,7 +3463,7 @@ var Choices = /** @class */ (function () {
3401
3463
  if (notice && notice.type === NoticeTypes.noChoices) {
3402
3464
  this._clearNotice();
3403
3465
  }
3404
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));
3466
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(item));
3405
3467
  };
3406
3468
  Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {
3407
3469
  if (withEvents === void 0) { withEvents = true; }
@@ -3516,25 +3578,25 @@ var Choices = /** @class */ (function () {
3516
3578
  containerInner.wrap(passedElement.element);
3517
3579
  // Wrapper inner container with outer container
3518
3580
  containerOuter.wrap(containerInner.element);
3581
+ containerOuter.element.appendChild(containerInner.element);
3582
+ containerOuter.element.appendChild(dropdownElement);
3583
+ containerInner.element.appendChild(this.itemList.element);
3584
+ dropdownElement.appendChild(this.choiceList.element);
3519
3585
  if (this._isSelectOneElement) {
3520
3586
  this.input.placeholder = this.config.searchPlaceholderValue || '';
3587
+ if (this.config.searchEnabled) {
3588
+ dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3589
+ }
3521
3590
  }
3522
3591
  else {
3592
+ if (!this._isSelectMultipleElement || this.config.searchEnabled) {
3593
+ containerInner.element.appendChild(this.input.element);
3594
+ }
3523
3595
  if (this._placeholderValue) {
3524
3596
  this.input.placeholder = this._placeholderValue;
3525
3597
  }
3526
3598
  this.input.setWidth();
3527
3599
  }
3528
- containerOuter.element.appendChild(containerInner.element);
3529
- containerOuter.element.appendChild(dropdownElement);
3530
- containerInner.element.appendChild(this.itemList.element);
3531
- dropdownElement.appendChild(this.choiceList.element);
3532
- if (!this._isSelectOneElement) {
3533
- containerInner.element.appendChild(this.input.element);
3534
- }
3535
- else if (this.config.searchEnabled) {
3536
- dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3537
- }
3538
3600
  this._highlightPosition = 0;
3539
3601
  this._isSearching = false;
3540
3602
  };
@@ -3616,7 +3678,7 @@ var Choices = /** @class */ (function () {
3616
3678
  throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it"));
3617
3679
  }
3618
3680
  };
3619
- Choices.version = '11.1.0';
3681
+ Choices.version = '11.2.1';
3620
3682
  return Choices;
3621
3683
  }());
3622
3684