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
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -217,9 +217,6 @@
217
217
  return firstChild;
218
218
  };
219
219
  })();
220
- var resolveNoticeFunction = function (fn, value) {
221
- return typeof fn === 'function' ? fn(sanitise(value), value) : fn;
222
- };
223
220
  var resolveStringFunction = function (fn) {
224
221
  return typeof fn === 'function' ? fn() : fn;
225
222
  };
@@ -251,6 +248,26 @@
251
248
  }
252
249
  return '';
253
250
  };
251
+ var getChoiceForOutput = function (choice, keyCode) {
252
+ return {
253
+ id: choice.id,
254
+ highlighted: choice.highlighted,
255
+ labelClass: choice.labelClass,
256
+ labelDescription: unwrapStringForRaw(choice.labelDescription),
257
+ customProperties: choice.customProperties,
258
+ disabled: choice.disabled,
259
+ active: choice.active,
260
+ label: choice.label,
261
+ placeholder: choice.placeholder,
262
+ value: choice.value,
263
+ groupValue: choice.group ? choice.group.label : undefined,
264
+ element: choice.element,
265
+ keyCode: keyCode,
266
+ };
267
+ };
268
+ var resolveNoticeFunction = function (fn, value, item) {
269
+ return typeof fn === 'function' ? fn(sanitise(value), unwrapStringForRaw(value), item) : fn;
270
+ };
254
271
  var escapeForTemplate = function (allowHTML, s) {
255
272
  return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);
256
273
  };
@@ -418,6 +435,12 @@
418
435
  Container.prototype.removeFocusState = function () {
419
436
  removeClassesFromElement(this.element, this.classNames.focusState);
420
437
  };
438
+ Container.prototype.addInvalidState = function () {
439
+ addClassesToElement(this.element, this.classNames.invalidState);
440
+ };
441
+ Container.prototype.removeInvalidState = function () {
442
+ removeClassesFromElement(this.element, this.classNames.invalidState);
443
+ };
421
444
  Container.prototype.enable = function () {
422
445
  removeClassesFromElement(this.element, this.classNames.disabledState);
423
446
  this.element.removeAttribute('aria-disabled');
@@ -883,7 +906,9 @@
883
906
  highlighted: false,
884
907
  placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),
885
908
  labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,
886
- labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined,
909
+ labelDescription: typeof option.dataset.labelDescription !== 'undefined'
910
+ ? { trusted: option.dataset.labelDescription }
911
+ : undefined,
887
912
  customProperties: parseCustomProperties(option.dataset.customProperties),
888
913
  };
889
914
  };
@@ -929,6 +954,7 @@
929
954
  selectedState: ['is-selected'],
930
955
  flippedState: ['is-flipped'],
931
956
  loadingState: ['is-loading'],
957
+ invalidState: ['is-invalid'],
932
958
  notice: ['choices__notice'],
933
959
  addChoice: ['choices__item--selectable', 'add-choice'],
934
960
  noResults: ['has-no-results'],
@@ -956,6 +982,7 @@
956
982
  paste: true,
957
983
  searchEnabled: true,
958
984
  searchChoices: true,
985
+ searchDisabledChoices: false,
959
986
  searchFloor: 1,
960
987
  searchResultLimit: 4,
961
988
  searchFields: ['label', 'value'],
@@ -971,6 +998,7 @@
971
998
  prependValue: null,
972
999
  appendValue: null,
973
1000
  renderSelectedChoices: 'auto',
1001
+ searchRenderSelectedChoices: true,
974
1002
  loadingText: 'Loading...',
975
1003
  noResultsText: 'No results found',
976
1004
  noChoicesText: 'No choices to choose from',
@@ -979,7 +1007,9 @@
979
1007
  customAddItemText: 'Only values matching specific conditions can be added',
980
1008
  addItemText: function (value) { return "Press Enter to add <b>\"".concat(value, "\"</b>"); },
981
1009
  removeItemIconText: function () { return "Remove item"; },
982
- removeItemLabelText: function (value) { return "Remove item: ".concat(value); },
1010
+ removeItemLabelText: function (value, _valueRaw, i) {
1011
+ return "Remove item: ".concat(i ? sanitise(i.label) : value);
1012
+ },
983
1013
  maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); },
984
1014
  valueComparer: function (value1, value2) { return value1 === value2; },
985
1015
  fuseOptions: {
@@ -1280,7 +1310,8 @@
1280
1310
  * Get choices that can be searched (excluding placeholders or disabled choices)
1281
1311
  */
1282
1312
  get: function () {
1283
- return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; });
1313
+ var context = this._context;
1314
+ return this.choices.filter(function (choice) { return !choice.placeholder && (context.searchDisabledChoices || !choice.disabled); });
1284
1315
  },
1285
1316
  enumerable: false,
1286
1317
  configurable: true
@@ -1338,9 +1369,9 @@
1338
1369
  function _defineProperty(e, r, t) {
1339
1370
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1340
1371
  value: t,
1341
- enumerable: !0,
1342
- configurable: !0,
1343
- writable: !0
1372
+ enumerable: true,
1373
+ configurable: true,
1374
+ writable: true
1344
1375
  }) : e[r] = t, e;
1345
1376
  }
1346
1377
  function ownKeys(e, r) {
@@ -1356,7 +1387,7 @@
1356
1387
  function _objectSpread2(e) {
1357
1388
  for (var r = 1; r < arguments.length; r++) {
1358
1389
  var t = null != arguments[r] ? arguments[r] : {};
1359
- r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
1390
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
1360
1391
  _defineProperty(e, r, t[r]);
1361
1392
  }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
1362
1393
  Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
@@ -1368,7 +1399,7 @@
1368
1399
  if ("object" != typeof t || !t) return t;
1369
1400
  var e = t[Symbol.toPrimitive];
1370
1401
  if (void 0 !== e) {
1371
- var i = e.call(t, r || "default");
1402
+ var i = e.call(t, r);
1372
1403
  if ("object" != typeof i) return i;
1373
1404
  throw new TypeError("@@toPrimitive must return a primitive value.");
1374
1405
  }
@@ -1391,16 +1422,13 @@
1391
1422
  function isArray(value) {
1392
1423
  return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value);
1393
1424
  }
1394
-
1395
- // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js
1396
- const INFINITY = 1 / 0;
1397
1425
  function baseToString(value) {
1398
1426
  // Exit early for strings to avoid a performance hit in some environments.
1399
1427
  if (typeof value == 'string') {
1400
1428
  return value;
1401
1429
  }
1402
1430
  let result = value + '';
1403
- return result == '0' && 1 / value == -INFINITY ? '-0' : result;
1431
+ return result == '0' && 1 / value == -Infinity ? '-0' : result;
1404
1432
  }
1405
1433
  function toString(value) {
1406
1434
  return value == null ? '' : baseToString(value);
@@ -1436,7 +1464,6 @@
1436
1464
  function getTag(value) {
1437
1465
  return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value);
1438
1466
  }
1439
- const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';
1440
1467
  const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
1441
1468
  const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`;
1442
1469
  const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`;
@@ -2690,9 +2717,7 @@
2690
2717
  class Fuse {
2691
2718
  constructor(docs, options = {}, index) {
2692
2719
  this.options = _objectSpread2(_objectSpread2({}, Config), options);
2693
- if (this.options.useExtendedSearch && !true) {
2694
- throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
2695
- }
2720
+ if (this.options.useExtendedSearch && false) ;
2696
2721
  this._keyStore = new KeyStore(this.options.keys);
2697
2722
  this.setCollection(docs, index);
2698
2723
  }
@@ -3024,7 +3049,7 @@
3024
3049
  dataset.labelClass = getClassNames(labelClass).join(' ');
3025
3050
  }
3026
3051
  if (labelDescription) {
3027
- dataset.labelDescription = labelDescription;
3052
+ dataset.labelDescription = unwrapStringForRaw(labelDescription);
3028
3053
  }
3029
3054
  if (withCustomProperties && customProperties) {
3030
3055
  if (typeof customProperties === 'string') {
@@ -3131,8 +3156,9 @@
3131
3156
  var removeButton = document.createElement('button');
3132
3157
  removeButton.type = 'button';
3133
3158
  addClassesToElement(removeButton, button);
3134
- setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));
3135
- var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);
3159
+ var eventChoice = getChoiceForOutput(choice);
3160
+ setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value, eventChoice));
3161
+ var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value, eventChoice);
3136
3162
  if (REMOVE_ITEM_LABEL) {
3137
3163
  removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);
3138
3164
  }
@@ -3237,6 +3263,7 @@
3237
3263
  else {
3238
3264
  addClassesToElement(div, itemSelectable);
3239
3265
  div.dataset.choiceSelectable = '';
3266
+ div.setAttribute('aria-selected', choice.selected ? 'true' : 'false');
3240
3267
  }
3241
3268
  return div;
3242
3269
  },
@@ -3406,7 +3433,7 @@
3406
3433
  this.initialised = false;
3407
3434
  this._store = new Store(config);
3408
3435
  this._currentValue = '';
3409
- config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;
3436
+ config.searchEnabled = !isText && config.searchEnabled;
3410
3437
  this._canSearch = config.searchEnabled;
3411
3438
  this._isScrollingOnIe = false;
3412
3439
  this._highlightPosition = 0;
@@ -3446,6 +3473,8 @@
3446
3473
  this._onEscapeKey = this._onEscapeKey.bind(this);
3447
3474
  this._onDirectionKey = this._onDirectionKey.bind(this);
3448
3475
  this._onDeleteKey = this._onDeleteKey.bind(this);
3476
+ this._onChange = this._onChange.bind(this);
3477
+ this._onInvalid = this._onInvalid.bind(this);
3449
3478
  // If element has already been initialised with Choices, fail silently
3450
3479
  if (this.passedElement.isActive) {
3451
3480
  if (!config.silent) {
@@ -3552,7 +3581,7 @@
3552
3581
  }
3553
3582
  this._store.dispatch(highlightItem(choice, true));
3554
3583
  if (runEvent) {
3555
- this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));
3584
+ this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(choice));
3556
3585
  }
3557
3586
  return this;
3558
3587
  };
@@ -3567,7 +3596,7 @@
3567
3596
  }
3568
3597
  this._store.dispatch(highlightItem(choice, false));
3569
3598
  if (runEvent) {
3570
- this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));
3599
+ this.passedElement.triggerEvent(EventType.unhighlightItem, getChoiceForOutput(choice));
3571
3600
  }
3572
3601
  return this;
3573
3602
  };
@@ -3577,7 +3606,7 @@
3577
3606
  _this._store.items.forEach(function (item) {
3578
3607
  if (!item.highlighted) {
3579
3608
  _this._store.dispatch(highlightItem(item, true));
3580
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
3609
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
3581
3610
  }
3582
3611
  });
3583
3612
  });
@@ -3589,7 +3618,7 @@
3589
3618
  _this._store.items.forEach(function (item) {
3590
3619
  if (item.highlighted) {
3591
3620
  _this._store.dispatch(highlightItem(item, false));
3592
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
3621
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
3593
3622
  }
3594
3623
  });
3595
3624
  });
@@ -3644,6 +3673,11 @@
3644
3673
  _this.input.focus();
3645
3674
  }
3646
3675
  _this.passedElement.triggerEvent(EventType.showDropdown);
3676
+ var activeElement = _this.choiceList.element.querySelector(getClassNamesSelector(_this.config.classNames.selectedState));
3677
+ if (activeElement !== null && !isScrolledIntoView(activeElement, _this.choiceList.element)) {
3678
+ // We use the native scrollIntoView function instead of choiceList.scrollToChildElement to avoid animated scroll.
3679
+ activeElement.scrollIntoView();
3680
+ }
3647
3681
  });
3648
3682
  return this;
3649
3683
  };
@@ -3652,6 +3686,7 @@
3652
3686
  if (!this.dropdown.isActive) {
3653
3687
  return this;
3654
3688
  }
3689
+ this._removeHighlightedChoices();
3655
3690
  requestAnimationFrame(function () {
3656
3691
  _this.dropdown.hide();
3657
3692
  _this.containerOuter.close();
@@ -3664,9 +3699,8 @@
3664
3699
  return this;
3665
3700
  };
3666
3701
  Choices.prototype.getValue = function (valueOnly) {
3667
- var _this = this;
3668
3702
  var values = this._store.items.map(function (item) {
3669
- return (valueOnly ? item.value : _this._getChoiceForOutput(item));
3703
+ return (valueOnly ? item.value : getChoiceForOutput(item));
3670
3704
  });
3671
3705
  return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;
3672
3706
  };
@@ -3924,7 +3958,7 @@
3924
3958
  // @todo integrate with Store
3925
3959
  this._searcher.reset();
3926
3960
  if (choice.selected) {
3927
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));
3961
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(choice));
3928
3962
  }
3929
3963
  return this;
3930
3964
  };
@@ -4007,13 +4041,7 @@
4007
4041
  }
4008
4042
  var _a = this, config = _a.config, isSearching = _a._isSearching;
4009
4043
  var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;
4010
- var renderLimit = 0;
4011
- if (isSearching && config.searchResultLimit > 0) {
4012
- renderLimit = config.searchResultLimit;
4013
- }
4014
- else if (config.renderChoiceLimit > 0) {
4015
- renderLimit = config.renderChoiceLimit;
4016
- }
4044
+ var renderLimit = isSearching ? config.searchResultLimit : config.renderChoiceLimit;
4017
4045
  if (this._isSelectElement) {
4018
4046
  var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });
4019
4047
  if (backingOptions.length) {
@@ -4023,11 +4051,16 @@
4023
4051
  var fragment = document.createDocumentFragment();
4024
4052
  var renderableChoices = function (choices) {
4025
4053
  return choices.filter(function (choice) {
4026
- return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);
4054
+ return !choice.placeholder &&
4055
+ (isSearching
4056
+ ? (config.searchRenderSelectedChoices || !choice.selected) && !!choice.rank
4057
+ : config.renderSelectedChoices || !choice.selected);
4027
4058
  });
4028
4059
  };
4060
+ var showLabel = config.appendGroupInSearch && isSearching;
4029
4061
  var selectableChoices = false;
4030
- var renderChoices = function (choices, withinGroup, groupLabel) {
4062
+ var highlightedEl = null;
4063
+ var renderChoices = function (choices, withinGroup) {
4031
4064
  if (isSearching) {
4032
4065
  // sortByRank is used to ensure stable sorting, as scores are non-unique
4033
4066
  // this additionally ensures fuseOptions.sortFn is not ignored
@@ -4037,16 +4070,20 @@
4037
4070
  choices.sort(config.sorter);
4038
4071
  }
4039
4072
  var choiceLimit = choices.length;
4040
- choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;
4073
+ choiceLimit = !withinGroup && renderLimit > 0 && choiceLimit > renderLimit ? renderLimit : choiceLimit;
4041
4074
  choiceLimit--;
4042
4075
  choices.every(function (choice, index) {
4043
4076
  // choiceEl being empty signals the contents has probably significantly changed
4044
- var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);
4077
+ var dropdownItem = choice.choiceEl ||
4078
+ _this._templates.choice(config, choice, config.itemSelectText, showLabel && choice.group ? choice.group.label : undefined);
4045
4079
  choice.choiceEl = dropdownItem;
4046
4080
  fragment.appendChild(dropdownItem);
4047
4081
  if (isSearching || !choice.selected) {
4048
4082
  selectableChoices = true;
4049
4083
  }
4084
+ else if (!highlightedEl) {
4085
+ highlightedEl = dropdownItem;
4086
+ }
4050
4087
  return index < choiceLimit;
4051
4088
  });
4052
4089
  };
@@ -4056,7 +4093,7 @@
4056
4093
  }
4057
4094
  if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {
4058
4095
  // If we have a placeholder choice along with groups
4059
- renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);
4096
+ renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false);
4060
4097
  }
4061
4098
  // If we have grouped options
4062
4099
  if (activeGroups.length && !isSearching) {
@@ -4065,7 +4102,7 @@
4065
4102
  }
4066
4103
  // render Choices without group first, regardless of sort, otherwise they won't be distinguishable
4067
4104
  // from the last group
4068
- renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);
4105
+ renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false);
4069
4106
  activeGroups.forEach(function (group) {
4070
4107
  var groupChoices = renderableChoices(group.choices);
4071
4108
  if (groupChoices.length) {
@@ -4075,12 +4112,12 @@
4075
4112
  dropdownGroup.remove();
4076
4113
  fragment.appendChild(dropdownGroup);
4077
4114
  }
4078
- renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);
4115
+ renderChoices(groupChoices, true);
4079
4116
  }
4080
4117
  });
4081
4118
  }
4082
4119
  else {
4083
- renderChoices(renderableChoices(activeChoices), false, undefined);
4120
+ renderChoices(renderableChoices(activeChoices), false);
4084
4121
  }
4085
4122
  }
4086
4123
  if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {
@@ -4094,9 +4131,7 @@
4094
4131
  }
4095
4132
  this._renderNotice(fragment);
4096
4133
  this.choiceList.element.replaceChildren(fragment);
4097
- if (selectableChoices) {
4098
- this._highlightChoice();
4099
- }
4134
+ this._highlightChoice(highlightedEl);
4100
4135
  };
4101
4136
  Choices.prototype._renderItems = function () {
4102
4137
  var _this = this;
@@ -4206,23 +4241,12 @@
4206
4241
  }
4207
4242
  }
4208
4243
  };
4244
+ /**
4245
+ * @deprecated Use utils.getChoiceForOutput
4246
+ */
4209
4247
  // eslint-disable-next-line class-methods-use-this
4210
4248
  Choices.prototype._getChoiceForOutput = function (choice, keyCode) {
4211
- return {
4212
- id: choice.id,
4213
- highlighted: choice.highlighted,
4214
- labelClass: choice.labelClass,
4215
- labelDescription: choice.labelDescription,
4216
- customProperties: choice.customProperties,
4217
- disabled: choice.disabled,
4218
- active: choice.active,
4219
- label: choice.label,
4220
- placeholder: choice.placeholder,
4221
- value: choice.value,
4222
- groupValue: choice.group ? choice.group.label : undefined,
4223
- element: choice.element,
4224
- keyCode: keyCode,
4225
- };
4249
+ return getChoiceForOutput(choice, keyCode);
4226
4250
  };
4227
4251
  Choices.prototype._triggerChange = function (value) {
4228
4252
  if (value === undefined || value === null) {
@@ -4238,7 +4262,7 @@
4238
4262
  if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {
4239
4263
  return;
4240
4264
  }
4241
- var id = element && parseDataSetId(element.parentElement);
4265
+ var id = element && parseDataSetId(element.closest('[data-id]'));
4242
4266
  var itemToRemove = id && items.find(function (item) { return item.id === id; });
4243
4267
  if (!itemToRemove) {
4244
4268
  return;
@@ -4427,7 +4451,7 @@
4427
4451
  var notice = '';
4428
4452
  if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {
4429
4453
  canAddItem = false;
4430
- notice = resolveNoticeFunction(config.customAddItemText, value);
4454
+ notice = resolveNoticeFunction(config.customAddItemText, value, undefined);
4431
4455
  }
4432
4456
  if (canAddItem) {
4433
4457
  var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });
@@ -4439,12 +4463,12 @@
4439
4463
  }
4440
4464
  if (!config.duplicateItemsAllowed) {
4441
4465
  canAddItem = false;
4442
- notice = resolveNoticeFunction(config.uniqueItemText, value);
4466
+ notice = resolveNoticeFunction(config.uniqueItemText, value, undefined);
4443
4467
  }
4444
4468
  }
4445
4469
  }
4446
4470
  if (canAddItem) {
4447
- notice = resolveNoticeFunction(config.addItemText, value);
4471
+ notice = resolveNoticeFunction(config.addItemText, value, undefined);
4448
4472
  }
4449
4473
  if (notice) {
4450
4474
  this._displayNotice(notice, NoticeTypes.addChoice);
@@ -4495,6 +4519,7 @@
4495
4519
  var documentElement = this._docRoot;
4496
4520
  var outerElement = this.containerOuter.element;
4497
4521
  var inputElement = this.input.element;
4522
+ var passedElement = this.passedElement.element;
4498
4523
  // capture events - can cancel event processing or propagation
4499
4524
  documentElement.addEventListener('touchend', this._onTouchEnd, true);
4500
4525
  outerElement.addEventListener('keydown', this._onKeyDown, true);
@@ -4532,12 +4557,21 @@
4532
4557
  passive: true,
4533
4558
  });
4534
4559
  }
4560
+ if (passedElement.hasAttribute('required')) {
4561
+ passedElement.addEventListener('change', this._onChange, {
4562
+ passive: true,
4563
+ });
4564
+ passedElement.addEventListener('invalid', this._onInvalid, {
4565
+ passive: true,
4566
+ });
4567
+ }
4535
4568
  this.input.addEventListeners();
4536
4569
  };
4537
4570
  Choices.prototype._removeEventListeners = function () {
4538
4571
  var documentElement = this._docRoot;
4539
4572
  var outerElement = this.containerOuter.element;
4540
4573
  var inputElement = this.input.element;
4574
+ var passedElement = this.passedElement.element;
4541
4575
  documentElement.removeEventListener('touchend', this._onTouchEnd, true);
4542
4576
  outerElement.removeEventListener('keydown', this._onKeyDown, true);
4543
4577
  outerElement.removeEventListener('mousedown', this._onMouseDown, true);
@@ -4555,6 +4589,10 @@
4555
4589
  if (inputElement.form) {
4556
4590
  inputElement.form.removeEventListener('reset', this._onFormReset);
4557
4591
  }
4592
+ if (passedElement.hasAttribute('required')) {
4593
+ passedElement.removeEventListener('change', this._onChange);
4594
+ passedElement.removeEventListener('invalid', this._onInvalid);
4595
+ }
4558
4596
  this.input.removeEventListeners();
4559
4597
  };
4560
4598
  Choices.prototype._onKeyDown = function (event) {
@@ -4804,7 +4842,7 @@
4804
4842
  */
4805
4843
  Choices.prototype._onMouseDown = function (event) {
4806
4844
  var target = event.target;
4807
- if (!(target instanceof HTMLElement)) {
4845
+ if (!(target instanceof Element)) {
4808
4846
  return;
4809
4847
  }
4810
4848
  // If we have our mouse down on the scrollbar and are on IE11...
@@ -4913,7 +4951,7 @@
4913
4951
  // Remove the focus state when the past outerContainer was the target
4914
4952
  containerOuter.removeFocusState();
4915
4953
  // Also close the dropdown if search is disabled
4916
- if (!this._canSearch) {
4954
+ if (!this.config.searchEnabled) {
4917
4955
  this.hideDropdown(true);
4918
4956
  }
4919
4957
  }
@@ -4937,13 +4975,19 @@
4937
4975
  }
4938
4976
  });
4939
4977
  };
4940
- Choices.prototype._highlightChoice = function (el) {
4941
- if (el === void 0) { el = null; }
4942
- var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
4943
- if (!choices.length) {
4978
+ Choices.prototype._onChange = function (event) {
4979
+ if (!event.target.checkValidity()) {
4944
4980
  return;
4945
4981
  }
4946
- var passedEl = el;
4982
+ this.containerOuter.removeInvalidState();
4983
+ };
4984
+ Choices.prototype._onInvalid = function () {
4985
+ this.containerOuter.addInvalidState();
4986
+ };
4987
+ /**
4988
+ * Removes any highlighted choice options
4989
+ */
4990
+ Choices.prototype._removeHighlightedChoices = function () {
4947
4991
  var highlightedState = this.config.classNames.highlightedState;
4948
4992
  var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));
4949
4993
  // Remove any highlighted choices
@@ -4951,6 +4995,16 @@
4951
4995
  removeClassesFromElement(choice, highlightedState);
4952
4996
  choice.setAttribute('aria-selected', 'false');
4953
4997
  });
4998
+ };
4999
+ Choices.prototype._highlightChoice = function (el) {
5000
+ if (el === void 0) { el = null; }
5001
+ var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
5002
+ if (!choices.length) {
5003
+ return;
5004
+ }
5005
+ var passedEl = el;
5006
+ var highlightedState = this.config.classNames.highlightedState;
5007
+ this._removeHighlightedChoices();
4954
5008
  if (passedEl) {
4955
5009
  this._highlightPosition = choices.indexOf(passedEl);
4956
5010
  }
@@ -4991,9 +5045,10 @@
4991
5045
  }
4992
5046
  this._store.dispatch(addItem(item));
4993
5047
  if (withEvents) {
4994
- this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));
5048
+ var eventChoice = getChoiceForOutput(item);
5049
+ this.passedElement.triggerEvent(EventType.addItem, eventChoice);
4995
5050
  if (userTriggered) {
4996
- this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));
5051
+ this.passedElement.triggerEvent(EventType.choice, eventChoice);
4997
5052
  }
4998
5053
  }
4999
5054
  };
@@ -5006,7 +5061,7 @@
5006
5061
  if (notice && notice.type === NoticeTypes.noChoices) {
5007
5062
  this._clearNotice();
5008
5063
  }
5009
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));
5064
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(item));
5010
5065
  };
5011
5066
  Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {
5012
5067
  if (withEvents === void 0) { withEvents = true; }
@@ -5121,25 +5176,25 @@
5121
5176
  containerInner.wrap(passedElement.element);
5122
5177
  // Wrapper inner container with outer container
5123
5178
  containerOuter.wrap(containerInner.element);
5179
+ containerOuter.element.appendChild(containerInner.element);
5180
+ containerOuter.element.appendChild(dropdownElement);
5181
+ containerInner.element.appendChild(this.itemList.element);
5182
+ dropdownElement.appendChild(this.choiceList.element);
5124
5183
  if (this._isSelectOneElement) {
5125
5184
  this.input.placeholder = this.config.searchPlaceholderValue || '';
5185
+ if (this.config.searchEnabled) {
5186
+ dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
5187
+ }
5126
5188
  }
5127
5189
  else {
5190
+ if (!this._isSelectMultipleElement || this.config.searchEnabled) {
5191
+ containerInner.element.appendChild(this.input.element);
5192
+ }
5128
5193
  if (this._placeholderValue) {
5129
5194
  this.input.placeholder = this._placeholderValue;
5130
5195
  }
5131
5196
  this.input.setWidth();
5132
5197
  }
5133
- containerOuter.element.appendChild(containerInner.element);
5134
- containerOuter.element.appendChild(dropdownElement);
5135
- containerInner.element.appendChild(this.itemList.element);
5136
- dropdownElement.appendChild(this.choiceList.element);
5137
- if (!this._isSelectOneElement) {
5138
- containerInner.element.appendChild(this.input.element);
5139
- }
5140
- else if (this.config.searchEnabled) {
5141
- dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
5142
- }
5143
5198
  this._highlightPosition = 0;
5144
5199
  this._isSearching = false;
5145
5200
  };
@@ -5221,7 +5276,7 @@
5221
5276
  throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it"));
5222
5277
  }
5223
5278
  };
5224
- Choices.version = '11.1.0';
5279
+ Choices.version = '11.2.1';
5225
5280
  return Choices;
5226
5281
  }());
5227
5282