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.
@@ -211,9 +211,6 @@ var strToEl = (function () {
211
211
  return firstChild;
212
212
  };
213
213
  })();
214
- var resolveNoticeFunction = function (fn, value) {
215
- return typeof fn === 'function' ? fn(sanitise(value), value) : fn;
216
- };
217
214
  var resolveStringFunction = function (fn) {
218
215
  return typeof fn === 'function' ? fn() : fn;
219
216
  };
@@ -245,6 +242,26 @@ var unwrapStringForEscaped = function (s) {
245
242
  }
246
243
  return '';
247
244
  };
245
+ var getChoiceForOutput = function (choice, keyCode) {
246
+ return {
247
+ id: choice.id,
248
+ highlighted: choice.highlighted,
249
+ labelClass: choice.labelClass,
250
+ labelDescription: unwrapStringForRaw(choice.labelDescription),
251
+ customProperties: choice.customProperties,
252
+ disabled: choice.disabled,
253
+ active: choice.active,
254
+ label: choice.label,
255
+ placeholder: choice.placeholder,
256
+ value: choice.value,
257
+ groupValue: choice.group ? choice.group.label : undefined,
258
+ element: choice.element,
259
+ keyCode: keyCode,
260
+ };
261
+ };
262
+ var resolveNoticeFunction = function (fn, value, item) {
263
+ return typeof fn === 'function' ? fn(sanitise(value), unwrapStringForRaw(value), item) : fn;
264
+ };
248
265
  var escapeForTemplate = function (allowHTML, s) {
249
266
  return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);
250
267
  };
@@ -412,6 +429,12 @@ var Container = /** @class */ (function () {
412
429
  Container.prototype.removeFocusState = function () {
413
430
  removeClassesFromElement(this.element, this.classNames.focusState);
414
431
  };
432
+ Container.prototype.addInvalidState = function () {
433
+ addClassesToElement(this.element, this.classNames.invalidState);
434
+ };
435
+ Container.prototype.removeInvalidState = function () {
436
+ removeClassesFromElement(this.element, this.classNames.invalidState);
437
+ };
415
438
  Container.prototype.enable = function () {
416
439
  removeClassesFromElement(this.element, this.classNames.disabledState);
417
440
  this.element.removeAttribute('aria-disabled');
@@ -877,7 +900,9 @@ var WrappedSelect = /** @class */ (function (_super) {
877
900
  highlighted: false,
878
901
  placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),
879
902
  labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,
880
- labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined,
903
+ labelDescription: typeof option.dataset.labelDescription !== 'undefined'
904
+ ? { trusted: option.dataset.labelDescription }
905
+ : undefined,
881
906
  customProperties: parseCustomProperties(option.dataset.customProperties),
882
907
  };
883
908
  };
@@ -923,6 +948,7 @@ var DEFAULT_CLASSNAMES = {
923
948
  selectedState: ['is-selected'],
924
949
  flippedState: ['is-flipped'],
925
950
  loadingState: ['is-loading'],
951
+ invalidState: ['is-invalid'],
926
952
  notice: ['choices__notice'],
927
953
  addChoice: ['choices__item--selectable', 'add-choice'],
928
954
  noResults: ['has-no-results'],
@@ -950,6 +976,7 @@ var DEFAULT_CONFIG = {
950
976
  paste: true,
951
977
  searchEnabled: true,
952
978
  searchChoices: true,
979
+ searchDisabledChoices: false,
953
980
  searchFloor: 1,
954
981
  searchResultLimit: 4,
955
982
  searchFields: ['label', 'value'],
@@ -965,6 +992,7 @@ var DEFAULT_CONFIG = {
965
992
  prependValue: null,
966
993
  appendValue: null,
967
994
  renderSelectedChoices: 'auto',
995
+ searchRenderSelectedChoices: true,
968
996
  loadingText: 'Loading...',
969
997
  noResultsText: 'No results found',
970
998
  noChoicesText: 'No choices to choose from',
@@ -973,7 +1001,9 @@ var DEFAULT_CONFIG = {
973
1001
  customAddItemText: 'Only values matching specific conditions can be added',
974
1002
  addItemText: function (value) { return "Press Enter to add <b>\"".concat(value, "\"</b>"); },
975
1003
  removeItemIconText: function () { return "Remove item"; },
976
- removeItemLabelText: function (value) { return "Remove item: ".concat(value); },
1004
+ removeItemLabelText: function (value, _valueRaw, i) {
1005
+ return "Remove item: ".concat(i ? sanitise(i.label) : value);
1006
+ },
977
1007
  maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); },
978
1008
  valueComparer: function (value1, value2) { return value1 === value2; },
979
1009
  fuseOptions: {
@@ -1274,7 +1304,8 @@ var Store = /** @class */ (function () {
1274
1304
  * Get choices that can be searched (excluding placeholders or disabled choices)
1275
1305
  */
1276
1306
  get: function () {
1277
- return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; });
1307
+ var context = this._context;
1308
+ return this.choices.filter(function (choice) { return !choice.placeholder && (context.searchDisabledChoices || !choice.disabled); });
1278
1309
  },
1279
1310
  enumerable: false,
1280
1311
  configurable: true
@@ -1332,9 +1363,9 @@ var NoticeTypes = {
1332
1363
  function _defineProperty(e, r, t) {
1333
1364
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1334
1365
  value: t,
1335
- enumerable: !0,
1336
- configurable: !0,
1337
- writable: !0
1366
+ enumerable: true,
1367
+ configurable: true,
1368
+ writable: true
1338
1369
  }) : e[r] = t, e;
1339
1370
  }
1340
1371
  function ownKeys(e, r) {
@@ -1350,7 +1381,7 @@ function ownKeys(e, r) {
1350
1381
  function _objectSpread2(e) {
1351
1382
  for (var r = 1; r < arguments.length; r++) {
1352
1383
  var t = null != arguments[r] ? arguments[r] : {};
1353
- r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
1384
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
1354
1385
  _defineProperty(e, r, t[r]);
1355
1386
  }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
1356
1387
  Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
@@ -1362,7 +1393,7 @@ function _toPrimitive(t, r) {
1362
1393
  if ("object" != typeof t || !t) return t;
1363
1394
  var e = t[Symbol.toPrimitive];
1364
1395
  if (void 0 !== e) {
1365
- var i = e.call(t, r || "default");
1396
+ var i = e.call(t, r);
1366
1397
  if ("object" != typeof i) return i;
1367
1398
  throw new TypeError("@@toPrimitive must return a primitive value.");
1368
1399
  }
@@ -1385,16 +1416,13 @@ function _toPropertyKey(t) {
1385
1416
  function isArray(value) {
1386
1417
  return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value);
1387
1418
  }
1388
-
1389
- // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js
1390
- const INFINITY = 1 / 0;
1391
1419
  function baseToString(value) {
1392
1420
  // Exit early for strings to avoid a performance hit in some environments.
1393
1421
  if (typeof value == 'string') {
1394
1422
  return value;
1395
1423
  }
1396
1424
  let result = value + '';
1397
- return result == '0' && 1 / value == -INFINITY ? '-0' : result;
1425
+ return result == '0' && 1 / value == -Infinity ? '-0' : result;
1398
1426
  }
1399
1427
  function toString(value) {
1400
1428
  return value == null ? '' : baseToString(value);
@@ -2263,7 +2291,7 @@ function format(results, docs, {
2263
2291
  class Fuse {
2264
2292
  constructor(docs, options = {}, index) {
2265
2293
  this.options = _objectSpread2(_objectSpread2({}, Config), options);
2266
- if (this.options.useExtendedSearch && !false) {
2294
+ if (this.options.useExtendedSearch && true) {
2267
2295
  throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
2268
2296
  }
2269
2297
  this._keyStore = new KeyStore(this.options.keys);
@@ -2536,7 +2564,7 @@ var assignCustomProperties = function (el, choice, withCustomProperties) {
2536
2564
  dataset.labelClass = getClassNames(labelClass).join(' ');
2537
2565
  }
2538
2566
  if (labelDescription) {
2539
- dataset.labelDescription = labelDescription;
2567
+ dataset.labelDescription = unwrapStringForRaw(labelDescription);
2540
2568
  }
2541
2569
  if (withCustomProperties && customProperties) {
2542
2570
  if (typeof customProperties === 'string') {
@@ -2643,8 +2671,9 @@ var templates = {
2643
2671
  var removeButton = document.createElement('button');
2644
2672
  removeButton.type = 'button';
2645
2673
  addClassesToElement(removeButton, button);
2646
- setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));
2647
- var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);
2674
+ var eventChoice = getChoiceForOutput(choice);
2675
+ setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value, eventChoice));
2676
+ var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value, eventChoice);
2648
2677
  if (REMOVE_ITEM_LABEL) {
2649
2678
  removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);
2650
2679
  }
@@ -2749,6 +2778,7 @@ var templates = {
2749
2778
  else {
2750
2779
  addClassesToElement(div, itemSelectable);
2751
2780
  div.dataset.choiceSelectable = '';
2781
+ div.setAttribute('aria-selected', choice.selected ? 'true' : 'false');
2752
2782
  }
2753
2783
  return div;
2754
2784
  },
@@ -2918,7 +2948,7 @@ var Choices = /** @class */ (function () {
2918
2948
  this.initialised = false;
2919
2949
  this._store = new Store(config);
2920
2950
  this._currentValue = '';
2921
- config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;
2951
+ config.searchEnabled = !isText && config.searchEnabled;
2922
2952
  this._canSearch = config.searchEnabled;
2923
2953
  this._isScrollingOnIe = false;
2924
2954
  this._highlightPosition = 0;
@@ -2958,6 +2988,8 @@ var Choices = /** @class */ (function () {
2958
2988
  this._onEscapeKey = this._onEscapeKey.bind(this);
2959
2989
  this._onDirectionKey = this._onDirectionKey.bind(this);
2960
2990
  this._onDeleteKey = this._onDeleteKey.bind(this);
2991
+ this._onChange = this._onChange.bind(this);
2992
+ this._onInvalid = this._onInvalid.bind(this);
2961
2993
  // If element has already been initialised with Choices, fail silently
2962
2994
  if (this.passedElement.isActive) {
2963
2995
  if (!config.silent) {
@@ -3064,7 +3096,7 @@ var Choices = /** @class */ (function () {
3064
3096
  }
3065
3097
  this._store.dispatch(highlightItem(choice, true));
3066
3098
  if (runEvent) {
3067
- this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));
3099
+ this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(choice));
3068
3100
  }
3069
3101
  return this;
3070
3102
  };
@@ -3079,7 +3111,7 @@ var Choices = /** @class */ (function () {
3079
3111
  }
3080
3112
  this._store.dispatch(highlightItem(choice, false));
3081
3113
  if (runEvent) {
3082
- this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));
3114
+ this.passedElement.triggerEvent(EventType.unhighlightItem, getChoiceForOutput(choice));
3083
3115
  }
3084
3116
  return this;
3085
3117
  };
@@ -3089,7 +3121,7 @@ var Choices = /** @class */ (function () {
3089
3121
  _this._store.items.forEach(function (item) {
3090
3122
  if (!item.highlighted) {
3091
3123
  _this._store.dispatch(highlightItem(item, true));
3092
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
3124
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
3093
3125
  }
3094
3126
  });
3095
3127
  });
@@ -3101,7 +3133,7 @@ var Choices = /** @class */ (function () {
3101
3133
  _this._store.items.forEach(function (item) {
3102
3134
  if (item.highlighted) {
3103
3135
  _this._store.dispatch(highlightItem(item, false));
3104
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
3136
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
3105
3137
  }
3106
3138
  });
3107
3139
  });
@@ -3156,6 +3188,11 @@ var Choices = /** @class */ (function () {
3156
3188
  _this.input.focus();
3157
3189
  }
3158
3190
  _this.passedElement.triggerEvent(EventType.showDropdown);
3191
+ var activeElement = _this.choiceList.element.querySelector(getClassNamesSelector(_this.config.classNames.selectedState));
3192
+ if (activeElement !== null && !isScrolledIntoView(activeElement, _this.choiceList.element)) {
3193
+ // We use the native scrollIntoView function instead of choiceList.scrollToChildElement to avoid animated scroll.
3194
+ activeElement.scrollIntoView();
3195
+ }
3159
3196
  });
3160
3197
  return this;
3161
3198
  };
@@ -3164,6 +3201,7 @@ var Choices = /** @class */ (function () {
3164
3201
  if (!this.dropdown.isActive) {
3165
3202
  return this;
3166
3203
  }
3204
+ this._removeHighlightedChoices();
3167
3205
  requestAnimationFrame(function () {
3168
3206
  _this.dropdown.hide();
3169
3207
  _this.containerOuter.close();
@@ -3176,9 +3214,8 @@ var Choices = /** @class */ (function () {
3176
3214
  return this;
3177
3215
  };
3178
3216
  Choices.prototype.getValue = function (valueOnly) {
3179
- var _this = this;
3180
3217
  var values = this._store.items.map(function (item) {
3181
- return (valueOnly ? item.value : _this._getChoiceForOutput(item));
3218
+ return (valueOnly ? item.value : getChoiceForOutput(item));
3182
3219
  });
3183
3220
  return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;
3184
3221
  };
@@ -3436,7 +3473,7 @@ var Choices = /** @class */ (function () {
3436
3473
  // @todo integrate with Store
3437
3474
  this._searcher.reset();
3438
3475
  if (choice.selected) {
3439
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));
3476
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(choice));
3440
3477
  }
3441
3478
  return this;
3442
3479
  };
@@ -3519,13 +3556,7 @@ var Choices = /** @class */ (function () {
3519
3556
  }
3520
3557
  var _a = this, config = _a.config, isSearching = _a._isSearching;
3521
3558
  var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;
3522
- var renderLimit = 0;
3523
- if (isSearching && config.searchResultLimit > 0) {
3524
- renderLimit = config.searchResultLimit;
3525
- }
3526
- else if (config.renderChoiceLimit > 0) {
3527
- renderLimit = config.renderChoiceLimit;
3528
- }
3559
+ var renderLimit = isSearching ? config.searchResultLimit : config.renderChoiceLimit;
3529
3560
  if (this._isSelectElement) {
3530
3561
  var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });
3531
3562
  if (backingOptions.length) {
@@ -3535,11 +3566,16 @@ var Choices = /** @class */ (function () {
3535
3566
  var fragment = document.createDocumentFragment();
3536
3567
  var renderableChoices = function (choices) {
3537
3568
  return choices.filter(function (choice) {
3538
- return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);
3569
+ return !choice.placeholder &&
3570
+ (isSearching
3571
+ ? (config.searchRenderSelectedChoices || !choice.selected) && !!choice.rank
3572
+ : config.renderSelectedChoices || !choice.selected);
3539
3573
  });
3540
3574
  };
3575
+ var showLabel = config.appendGroupInSearch && isSearching;
3541
3576
  var selectableChoices = false;
3542
- var renderChoices = function (choices, withinGroup, groupLabel) {
3577
+ var highlightedEl = null;
3578
+ var renderChoices = function (choices, withinGroup) {
3543
3579
  if (isSearching) {
3544
3580
  // sortByRank is used to ensure stable sorting, as scores are non-unique
3545
3581
  // this additionally ensures fuseOptions.sortFn is not ignored
@@ -3549,16 +3585,20 @@ var Choices = /** @class */ (function () {
3549
3585
  choices.sort(config.sorter);
3550
3586
  }
3551
3587
  var choiceLimit = choices.length;
3552
- choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;
3588
+ choiceLimit = !withinGroup && renderLimit > 0 && choiceLimit > renderLimit ? renderLimit : choiceLimit;
3553
3589
  choiceLimit--;
3554
3590
  choices.every(function (choice, index) {
3555
3591
  // choiceEl being empty signals the contents has probably significantly changed
3556
- var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);
3592
+ var dropdownItem = choice.choiceEl ||
3593
+ _this._templates.choice(config, choice, config.itemSelectText, showLabel && choice.group ? choice.group.label : undefined);
3557
3594
  choice.choiceEl = dropdownItem;
3558
3595
  fragment.appendChild(dropdownItem);
3559
3596
  if (isSearching || !choice.selected) {
3560
3597
  selectableChoices = true;
3561
3598
  }
3599
+ else if (!highlightedEl) {
3600
+ highlightedEl = dropdownItem;
3601
+ }
3562
3602
  return index < choiceLimit;
3563
3603
  });
3564
3604
  };
@@ -3568,7 +3608,7 @@ var Choices = /** @class */ (function () {
3568
3608
  }
3569
3609
  if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {
3570
3610
  // If we have a placeholder choice along with groups
3571
- renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);
3611
+ renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false);
3572
3612
  }
3573
3613
  // If we have grouped options
3574
3614
  if (activeGroups.length && !isSearching) {
@@ -3577,7 +3617,7 @@ var Choices = /** @class */ (function () {
3577
3617
  }
3578
3618
  // render Choices without group first, regardless of sort, otherwise they won't be distinguishable
3579
3619
  // from the last group
3580
- renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);
3620
+ renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false);
3581
3621
  activeGroups.forEach(function (group) {
3582
3622
  var groupChoices = renderableChoices(group.choices);
3583
3623
  if (groupChoices.length) {
@@ -3587,12 +3627,12 @@ var Choices = /** @class */ (function () {
3587
3627
  dropdownGroup.remove();
3588
3628
  fragment.appendChild(dropdownGroup);
3589
3629
  }
3590
- renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);
3630
+ renderChoices(groupChoices, true);
3591
3631
  }
3592
3632
  });
3593
3633
  }
3594
3634
  else {
3595
- renderChoices(renderableChoices(activeChoices), false, undefined);
3635
+ renderChoices(renderableChoices(activeChoices), false);
3596
3636
  }
3597
3637
  }
3598
3638
  if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {
@@ -3606,9 +3646,7 @@ var Choices = /** @class */ (function () {
3606
3646
  }
3607
3647
  this._renderNotice(fragment);
3608
3648
  this.choiceList.element.replaceChildren(fragment);
3609
- if (selectableChoices) {
3610
- this._highlightChoice();
3611
- }
3649
+ this._highlightChoice(highlightedEl);
3612
3650
  };
3613
3651
  Choices.prototype._renderItems = function () {
3614
3652
  var _this = this;
@@ -3718,23 +3756,12 @@ var Choices = /** @class */ (function () {
3718
3756
  }
3719
3757
  }
3720
3758
  };
3759
+ /**
3760
+ * @deprecated Use utils.getChoiceForOutput
3761
+ */
3721
3762
  // eslint-disable-next-line class-methods-use-this
3722
3763
  Choices.prototype._getChoiceForOutput = function (choice, keyCode) {
3723
- return {
3724
- id: choice.id,
3725
- highlighted: choice.highlighted,
3726
- labelClass: choice.labelClass,
3727
- labelDescription: choice.labelDescription,
3728
- customProperties: choice.customProperties,
3729
- disabled: choice.disabled,
3730
- active: choice.active,
3731
- label: choice.label,
3732
- placeholder: choice.placeholder,
3733
- value: choice.value,
3734
- groupValue: choice.group ? choice.group.label : undefined,
3735
- element: choice.element,
3736
- keyCode: keyCode,
3737
- };
3764
+ return getChoiceForOutput(choice, keyCode);
3738
3765
  };
3739
3766
  Choices.prototype._triggerChange = function (value) {
3740
3767
  if (value === undefined || value === null) {
@@ -3750,7 +3777,7 @@ var Choices = /** @class */ (function () {
3750
3777
  if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {
3751
3778
  return;
3752
3779
  }
3753
- var id = element && parseDataSetId(element.parentElement);
3780
+ var id = element && parseDataSetId(element.closest('[data-id]'));
3754
3781
  var itemToRemove = id && items.find(function (item) { return item.id === id; });
3755
3782
  if (!itemToRemove) {
3756
3783
  return;
@@ -3939,7 +3966,7 @@ var Choices = /** @class */ (function () {
3939
3966
  var notice = '';
3940
3967
  if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {
3941
3968
  canAddItem = false;
3942
- notice = resolveNoticeFunction(config.customAddItemText, value);
3969
+ notice = resolveNoticeFunction(config.customAddItemText, value, undefined);
3943
3970
  }
3944
3971
  if (canAddItem) {
3945
3972
  var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });
@@ -3951,12 +3978,12 @@ var Choices = /** @class */ (function () {
3951
3978
  }
3952
3979
  if (!config.duplicateItemsAllowed) {
3953
3980
  canAddItem = false;
3954
- notice = resolveNoticeFunction(config.uniqueItemText, value);
3981
+ notice = resolveNoticeFunction(config.uniqueItemText, value, undefined);
3955
3982
  }
3956
3983
  }
3957
3984
  }
3958
3985
  if (canAddItem) {
3959
- notice = resolveNoticeFunction(config.addItemText, value);
3986
+ notice = resolveNoticeFunction(config.addItemText, value, undefined);
3960
3987
  }
3961
3988
  if (notice) {
3962
3989
  this._displayNotice(notice, NoticeTypes.addChoice);
@@ -4007,6 +4034,7 @@ var Choices = /** @class */ (function () {
4007
4034
  var documentElement = this._docRoot;
4008
4035
  var outerElement = this.containerOuter.element;
4009
4036
  var inputElement = this.input.element;
4037
+ var passedElement = this.passedElement.element;
4010
4038
  // capture events - can cancel event processing or propagation
4011
4039
  documentElement.addEventListener('touchend', this._onTouchEnd, true);
4012
4040
  outerElement.addEventListener('keydown', this._onKeyDown, true);
@@ -4044,12 +4072,21 @@ var Choices = /** @class */ (function () {
4044
4072
  passive: true,
4045
4073
  });
4046
4074
  }
4075
+ if (passedElement.hasAttribute('required')) {
4076
+ passedElement.addEventListener('change', this._onChange, {
4077
+ passive: true,
4078
+ });
4079
+ passedElement.addEventListener('invalid', this._onInvalid, {
4080
+ passive: true,
4081
+ });
4082
+ }
4047
4083
  this.input.addEventListeners();
4048
4084
  };
4049
4085
  Choices.prototype._removeEventListeners = function () {
4050
4086
  var documentElement = this._docRoot;
4051
4087
  var outerElement = this.containerOuter.element;
4052
4088
  var inputElement = this.input.element;
4089
+ var passedElement = this.passedElement.element;
4053
4090
  documentElement.removeEventListener('touchend', this._onTouchEnd, true);
4054
4091
  outerElement.removeEventListener('keydown', this._onKeyDown, true);
4055
4092
  outerElement.removeEventListener('mousedown', this._onMouseDown, true);
@@ -4067,6 +4104,10 @@ var Choices = /** @class */ (function () {
4067
4104
  if (inputElement.form) {
4068
4105
  inputElement.form.removeEventListener('reset', this._onFormReset);
4069
4106
  }
4107
+ if (passedElement.hasAttribute('required')) {
4108
+ passedElement.removeEventListener('change', this._onChange);
4109
+ passedElement.removeEventListener('invalid', this._onInvalid);
4110
+ }
4070
4111
  this.input.removeEventListeners();
4071
4112
  };
4072
4113
  Choices.prototype._onKeyDown = function (event) {
@@ -4316,7 +4357,7 @@ var Choices = /** @class */ (function () {
4316
4357
  */
4317
4358
  Choices.prototype._onMouseDown = function (event) {
4318
4359
  var target = event.target;
4319
- if (!(target instanceof HTMLElement)) {
4360
+ if (!(target instanceof Element)) {
4320
4361
  return;
4321
4362
  }
4322
4363
  // If we have our mouse down on the scrollbar and are on IE11...
@@ -4425,7 +4466,7 @@ var Choices = /** @class */ (function () {
4425
4466
  // Remove the focus state when the past outerContainer was the target
4426
4467
  containerOuter.removeFocusState();
4427
4468
  // Also close the dropdown if search is disabled
4428
- if (!this._canSearch) {
4469
+ if (!this.config.searchEnabled) {
4429
4470
  this.hideDropdown(true);
4430
4471
  }
4431
4472
  }
@@ -4449,13 +4490,19 @@ var Choices = /** @class */ (function () {
4449
4490
  }
4450
4491
  });
4451
4492
  };
4452
- Choices.prototype._highlightChoice = function (el) {
4453
- if (el === void 0) { el = null; }
4454
- var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
4455
- if (!choices.length) {
4493
+ Choices.prototype._onChange = function (event) {
4494
+ if (!event.target.checkValidity()) {
4456
4495
  return;
4457
4496
  }
4458
- var passedEl = el;
4497
+ this.containerOuter.removeInvalidState();
4498
+ };
4499
+ Choices.prototype._onInvalid = function () {
4500
+ this.containerOuter.addInvalidState();
4501
+ };
4502
+ /**
4503
+ * Removes any highlighted choice options
4504
+ */
4505
+ Choices.prototype._removeHighlightedChoices = function () {
4459
4506
  var highlightedState = this.config.classNames.highlightedState;
4460
4507
  var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));
4461
4508
  // Remove any highlighted choices
@@ -4463,6 +4510,16 @@ var Choices = /** @class */ (function () {
4463
4510
  removeClassesFromElement(choice, highlightedState);
4464
4511
  choice.setAttribute('aria-selected', 'false');
4465
4512
  });
4513
+ };
4514
+ Choices.prototype._highlightChoice = function (el) {
4515
+ if (el === void 0) { el = null; }
4516
+ var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
4517
+ if (!choices.length) {
4518
+ return;
4519
+ }
4520
+ var passedEl = el;
4521
+ var highlightedState = this.config.classNames.highlightedState;
4522
+ this._removeHighlightedChoices();
4466
4523
  if (passedEl) {
4467
4524
  this._highlightPosition = choices.indexOf(passedEl);
4468
4525
  }
@@ -4503,9 +4560,10 @@ var Choices = /** @class */ (function () {
4503
4560
  }
4504
4561
  this._store.dispatch(addItem(item));
4505
4562
  if (withEvents) {
4506
- this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));
4563
+ var eventChoice = getChoiceForOutput(item);
4564
+ this.passedElement.triggerEvent(EventType.addItem, eventChoice);
4507
4565
  if (userTriggered) {
4508
- this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));
4566
+ this.passedElement.triggerEvent(EventType.choice, eventChoice);
4509
4567
  }
4510
4568
  }
4511
4569
  };
@@ -4518,7 +4576,7 @@ var Choices = /** @class */ (function () {
4518
4576
  if (notice && notice.type === NoticeTypes.noChoices) {
4519
4577
  this._clearNotice();
4520
4578
  }
4521
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));
4579
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(item));
4522
4580
  };
4523
4581
  Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {
4524
4582
  if (withEvents === void 0) { withEvents = true; }
@@ -4633,25 +4691,25 @@ var Choices = /** @class */ (function () {
4633
4691
  containerInner.wrap(passedElement.element);
4634
4692
  // Wrapper inner container with outer container
4635
4693
  containerOuter.wrap(containerInner.element);
4694
+ containerOuter.element.appendChild(containerInner.element);
4695
+ containerOuter.element.appendChild(dropdownElement);
4696
+ containerInner.element.appendChild(this.itemList.element);
4697
+ dropdownElement.appendChild(this.choiceList.element);
4636
4698
  if (this._isSelectOneElement) {
4637
4699
  this.input.placeholder = this.config.searchPlaceholderValue || '';
4700
+ if (this.config.searchEnabled) {
4701
+ dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
4702
+ }
4638
4703
  }
4639
4704
  else {
4705
+ if (!this._isSelectMultipleElement || this.config.searchEnabled) {
4706
+ containerInner.element.appendChild(this.input.element);
4707
+ }
4640
4708
  if (this._placeholderValue) {
4641
4709
  this.input.placeholder = this._placeholderValue;
4642
4710
  }
4643
4711
  this.input.setWidth();
4644
4712
  }
4645
- containerOuter.element.appendChild(containerInner.element);
4646
- containerOuter.element.appendChild(dropdownElement);
4647
- containerInner.element.appendChild(this.itemList.element);
4648
- dropdownElement.appendChild(this.choiceList.element);
4649
- if (!this._isSelectOneElement) {
4650
- containerInner.element.appendChild(this.input.element);
4651
- }
4652
- else if (this.config.searchEnabled) {
4653
- dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
4654
- }
4655
4713
  this._highlightPosition = 0;
4656
4714
  this._isSearching = false;
4657
4715
  };
@@ -4733,7 +4791,7 @@ var Choices = /** @class */ (function () {
4733
4791
  throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it"));
4734
4792
  }
4735
4793
  };
4736
- Choices.version = '11.1.0';
4794
+ Choices.version = '11.2.1';
4737
4795
  return Choices;
4738
4796
  }());
4739
4797