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() :
@@ -208,9 +208,6 @@
208
208
  return firstChild;
209
209
  };
210
210
  })();
211
- var resolveNoticeFunction = function (fn, value) {
212
- return typeof fn === 'function' ? fn(sanitise(value), value) : fn;
213
- };
214
211
  var resolveStringFunction = function (fn) {
215
212
  return typeof fn === 'function' ? fn() : fn;
216
213
  };
@@ -242,6 +239,26 @@
242
239
  }
243
240
  return '';
244
241
  };
242
+ var getChoiceForOutput = function (choice, keyCode) {
243
+ return {
244
+ id: choice.id,
245
+ highlighted: choice.highlighted,
246
+ labelClass: choice.labelClass,
247
+ labelDescription: unwrapStringForRaw(choice.labelDescription),
248
+ customProperties: choice.customProperties,
249
+ disabled: choice.disabled,
250
+ active: choice.active,
251
+ label: choice.label,
252
+ placeholder: choice.placeholder,
253
+ value: choice.value,
254
+ groupValue: choice.group ? choice.group.label : undefined,
255
+ element: choice.element,
256
+ keyCode: keyCode,
257
+ };
258
+ };
259
+ var resolveNoticeFunction = function (fn, value, item) {
260
+ return typeof fn === 'function' ? fn(sanitise(value), unwrapStringForRaw(value), item) : fn;
261
+ };
245
262
  var escapeForTemplate = function (allowHTML, s) {
246
263
  return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);
247
264
  };
@@ -409,6 +426,12 @@
409
426
  Container.prototype.removeFocusState = function () {
410
427
  removeClassesFromElement(this.element, this.classNames.focusState);
411
428
  };
429
+ Container.prototype.addInvalidState = function () {
430
+ addClassesToElement(this.element, this.classNames.invalidState);
431
+ };
432
+ Container.prototype.removeInvalidState = function () {
433
+ removeClassesFromElement(this.element, this.classNames.invalidState);
434
+ };
412
435
  Container.prototype.enable = function () {
413
436
  removeClassesFromElement(this.element, this.classNames.disabledState);
414
437
  this.element.removeAttribute('aria-disabled');
@@ -874,7 +897,9 @@
874
897
  highlighted: false,
875
898
  placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),
876
899
  labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,
877
- labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined,
900
+ labelDescription: typeof option.dataset.labelDescription !== 'undefined'
901
+ ? { trusted: option.dataset.labelDescription }
902
+ : undefined,
878
903
  customProperties: parseCustomProperties(option.dataset.customProperties),
879
904
  };
880
905
  };
@@ -920,6 +945,7 @@
920
945
  selectedState: ['is-selected'],
921
946
  flippedState: ['is-flipped'],
922
947
  loadingState: ['is-loading'],
948
+ invalidState: ['is-invalid'],
923
949
  notice: ['choices__notice'],
924
950
  addChoice: ['choices__item--selectable', 'add-choice'],
925
951
  noResults: ['has-no-results'],
@@ -947,6 +973,7 @@
947
973
  paste: true,
948
974
  searchEnabled: true,
949
975
  searchChoices: true,
976
+ searchDisabledChoices: false,
950
977
  searchFloor: 1,
951
978
  searchResultLimit: 4,
952
979
  searchFields: ['label', 'value'],
@@ -962,6 +989,7 @@
962
989
  prependValue: null,
963
990
  appendValue: null,
964
991
  renderSelectedChoices: 'auto',
992
+ searchRenderSelectedChoices: true,
965
993
  loadingText: 'Loading...',
966
994
  noResultsText: 'No results found',
967
995
  noChoicesText: 'No choices to choose from',
@@ -970,7 +998,9 @@
970
998
  customAddItemText: 'Only values matching specific conditions can be added',
971
999
  addItemText: function (value) { return "Press Enter to add <b>\"".concat(value, "\"</b>"); },
972
1000
  removeItemIconText: function () { return "Remove item"; },
973
- removeItemLabelText: function (value) { return "Remove item: ".concat(value); },
1001
+ removeItemLabelText: function (value, _valueRaw, i) {
1002
+ return "Remove item: ".concat(i ? sanitise(i.label) : value);
1003
+ },
974
1004
  maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); },
975
1005
  valueComparer: function (value1, value2) { return value1 === value2; },
976
1006
  fuseOptions: {
@@ -1271,7 +1301,8 @@
1271
1301
  * Get choices that can be searched (excluding placeholders or disabled choices)
1272
1302
  */
1273
1303
  get: function () {
1274
- return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; });
1304
+ var context = this._context;
1305
+ return this.choices.filter(function (choice) { return !choice.placeholder && (context.searchDisabledChoices || !choice.disabled); });
1275
1306
  },
1276
1307
  enumerable: false,
1277
1308
  configurable: true
@@ -1385,11 +1416,12 @@
1385
1416
  var field = this._fields[k];
1386
1417
  if (field in obj && kmpSearch(needle, obj[field].toLowerCase()) !== -1) {
1387
1418
  results.push({
1388
- item: obj[field],
1419
+ item: obj,
1389
1420
  score: count,
1390
1421
  rank: count + 1,
1391
1422
  });
1392
1423
  count++;
1424
+ break;
1393
1425
  }
1394
1426
  }
1395
1427
  }
@@ -1425,7 +1457,7 @@
1425
1457
  dataset.labelClass = getClassNames(labelClass).join(' ');
1426
1458
  }
1427
1459
  if (labelDescription) {
1428
- dataset.labelDescription = labelDescription;
1460
+ dataset.labelDescription = unwrapStringForRaw(labelDescription);
1429
1461
  }
1430
1462
  if (withCustomProperties && customProperties) {
1431
1463
  if (typeof customProperties === 'string') {
@@ -1532,8 +1564,9 @@
1532
1564
  var removeButton = document.createElement('button');
1533
1565
  removeButton.type = 'button';
1534
1566
  addClassesToElement(removeButton, button);
1535
- setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));
1536
- var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);
1567
+ var eventChoice = getChoiceForOutput(choice);
1568
+ setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value, eventChoice));
1569
+ var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value, eventChoice);
1537
1570
  if (REMOVE_ITEM_LABEL) {
1538
1571
  removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);
1539
1572
  }
@@ -1638,6 +1671,7 @@
1638
1671
  else {
1639
1672
  addClassesToElement(div, itemSelectable);
1640
1673
  div.dataset.choiceSelectable = '';
1674
+ div.setAttribute('aria-selected', choice.selected ? 'true' : 'false');
1641
1675
  }
1642
1676
  return div;
1643
1677
  },
@@ -1807,7 +1841,7 @@
1807
1841
  this.initialised = false;
1808
1842
  this._store = new Store(config);
1809
1843
  this._currentValue = '';
1810
- config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;
1844
+ config.searchEnabled = !isText && config.searchEnabled;
1811
1845
  this._canSearch = config.searchEnabled;
1812
1846
  this._isScrollingOnIe = false;
1813
1847
  this._highlightPosition = 0;
@@ -1847,6 +1881,8 @@
1847
1881
  this._onEscapeKey = this._onEscapeKey.bind(this);
1848
1882
  this._onDirectionKey = this._onDirectionKey.bind(this);
1849
1883
  this._onDeleteKey = this._onDeleteKey.bind(this);
1884
+ this._onChange = this._onChange.bind(this);
1885
+ this._onInvalid = this._onInvalid.bind(this);
1850
1886
  // If element has already been initialised with Choices, fail silently
1851
1887
  if (this.passedElement.isActive) {
1852
1888
  if (!config.silent) {
@@ -1953,7 +1989,7 @@
1953
1989
  }
1954
1990
  this._store.dispatch(highlightItem(choice, true));
1955
1991
  if (runEvent) {
1956
- this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));
1992
+ this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(choice));
1957
1993
  }
1958
1994
  return this;
1959
1995
  };
@@ -1968,7 +2004,7 @@
1968
2004
  }
1969
2005
  this._store.dispatch(highlightItem(choice, false));
1970
2006
  if (runEvent) {
1971
- this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));
2007
+ this.passedElement.triggerEvent(EventType.unhighlightItem, getChoiceForOutput(choice));
1972
2008
  }
1973
2009
  return this;
1974
2010
  };
@@ -1978,7 +2014,7 @@
1978
2014
  _this._store.items.forEach(function (item) {
1979
2015
  if (!item.highlighted) {
1980
2016
  _this._store.dispatch(highlightItem(item, true));
1981
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
2017
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1982
2018
  }
1983
2019
  });
1984
2020
  });
@@ -1990,7 +2026,7 @@
1990
2026
  _this._store.items.forEach(function (item) {
1991
2027
  if (item.highlighted) {
1992
2028
  _this._store.dispatch(highlightItem(item, false));
1993
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
2029
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1994
2030
  }
1995
2031
  });
1996
2032
  });
@@ -2045,6 +2081,11 @@
2045
2081
  _this.input.focus();
2046
2082
  }
2047
2083
  _this.passedElement.triggerEvent(EventType.showDropdown);
2084
+ var activeElement = _this.choiceList.element.querySelector(getClassNamesSelector(_this.config.classNames.selectedState));
2085
+ if (activeElement !== null && !isScrolledIntoView(activeElement, _this.choiceList.element)) {
2086
+ // We use the native scrollIntoView function instead of choiceList.scrollToChildElement to avoid animated scroll.
2087
+ activeElement.scrollIntoView();
2088
+ }
2048
2089
  });
2049
2090
  return this;
2050
2091
  };
@@ -2053,6 +2094,7 @@
2053
2094
  if (!this.dropdown.isActive) {
2054
2095
  return this;
2055
2096
  }
2097
+ this._removeHighlightedChoices();
2056
2098
  requestAnimationFrame(function () {
2057
2099
  _this.dropdown.hide();
2058
2100
  _this.containerOuter.close();
@@ -2065,9 +2107,8 @@
2065
2107
  return this;
2066
2108
  };
2067
2109
  Choices.prototype.getValue = function (valueOnly) {
2068
- var _this = this;
2069
2110
  var values = this._store.items.map(function (item) {
2070
- return (valueOnly ? item.value : _this._getChoiceForOutput(item));
2111
+ return (valueOnly ? item.value : getChoiceForOutput(item));
2071
2112
  });
2072
2113
  return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;
2073
2114
  };
@@ -2325,7 +2366,7 @@
2325
2366
  // @todo integrate with Store
2326
2367
  this._searcher.reset();
2327
2368
  if (choice.selected) {
2328
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));
2369
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(choice));
2329
2370
  }
2330
2371
  return this;
2331
2372
  };
@@ -2408,13 +2449,7 @@
2408
2449
  }
2409
2450
  var _a = this, config = _a.config, isSearching = _a._isSearching;
2410
2451
  var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;
2411
- var renderLimit = 0;
2412
- if (isSearching && config.searchResultLimit > 0) {
2413
- renderLimit = config.searchResultLimit;
2414
- }
2415
- else if (config.renderChoiceLimit > 0) {
2416
- renderLimit = config.renderChoiceLimit;
2417
- }
2452
+ var renderLimit = isSearching ? config.searchResultLimit : config.renderChoiceLimit;
2418
2453
  if (this._isSelectElement) {
2419
2454
  var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });
2420
2455
  if (backingOptions.length) {
@@ -2424,11 +2459,16 @@
2424
2459
  var fragment = document.createDocumentFragment();
2425
2460
  var renderableChoices = function (choices) {
2426
2461
  return choices.filter(function (choice) {
2427
- return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);
2462
+ return !choice.placeholder &&
2463
+ (isSearching
2464
+ ? (config.searchRenderSelectedChoices || !choice.selected) && !!choice.rank
2465
+ : config.renderSelectedChoices || !choice.selected);
2428
2466
  });
2429
2467
  };
2468
+ var showLabel = config.appendGroupInSearch && isSearching;
2430
2469
  var selectableChoices = false;
2431
- var renderChoices = function (choices, withinGroup, groupLabel) {
2470
+ var highlightedEl = null;
2471
+ var renderChoices = function (choices, withinGroup) {
2432
2472
  if (isSearching) {
2433
2473
  // sortByRank is used to ensure stable sorting, as scores are non-unique
2434
2474
  // this additionally ensures fuseOptions.sortFn is not ignored
@@ -2438,16 +2478,20 @@
2438
2478
  choices.sort(config.sorter);
2439
2479
  }
2440
2480
  var choiceLimit = choices.length;
2441
- choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2481
+ choiceLimit = !withinGroup && renderLimit > 0 && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2442
2482
  choiceLimit--;
2443
2483
  choices.every(function (choice, index) {
2444
2484
  // choiceEl being empty signals the contents has probably significantly changed
2445
- var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);
2485
+ var dropdownItem = choice.choiceEl ||
2486
+ _this._templates.choice(config, choice, config.itemSelectText, showLabel && choice.group ? choice.group.label : undefined);
2446
2487
  choice.choiceEl = dropdownItem;
2447
2488
  fragment.appendChild(dropdownItem);
2448
2489
  if (isSearching || !choice.selected) {
2449
2490
  selectableChoices = true;
2450
2491
  }
2492
+ else if (!highlightedEl) {
2493
+ highlightedEl = dropdownItem;
2494
+ }
2451
2495
  return index < choiceLimit;
2452
2496
  });
2453
2497
  };
@@ -2457,7 +2501,7 @@
2457
2501
  }
2458
2502
  if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {
2459
2503
  // If we have a placeholder choice along with groups
2460
- renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);
2504
+ renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false);
2461
2505
  }
2462
2506
  // If we have grouped options
2463
2507
  if (activeGroups.length && !isSearching) {
@@ -2466,7 +2510,7 @@
2466
2510
  }
2467
2511
  // render Choices without group first, regardless of sort, otherwise they won't be distinguishable
2468
2512
  // from the last group
2469
- renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);
2513
+ renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false);
2470
2514
  activeGroups.forEach(function (group) {
2471
2515
  var groupChoices = renderableChoices(group.choices);
2472
2516
  if (groupChoices.length) {
@@ -2476,12 +2520,12 @@
2476
2520
  dropdownGroup.remove();
2477
2521
  fragment.appendChild(dropdownGroup);
2478
2522
  }
2479
- renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);
2523
+ renderChoices(groupChoices, true);
2480
2524
  }
2481
2525
  });
2482
2526
  }
2483
2527
  else {
2484
- renderChoices(renderableChoices(activeChoices), false, undefined);
2528
+ renderChoices(renderableChoices(activeChoices), false);
2485
2529
  }
2486
2530
  }
2487
2531
  if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {
@@ -2495,9 +2539,7 @@
2495
2539
  }
2496
2540
  this._renderNotice(fragment);
2497
2541
  this.choiceList.element.replaceChildren(fragment);
2498
- if (selectableChoices) {
2499
- this._highlightChoice();
2500
- }
2542
+ this._highlightChoice(highlightedEl);
2501
2543
  };
2502
2544
  Choices.prototype._renderItems = function () {
2503
2545
  var _this = this;
@@ -2607,23 +2649,12 @@
2607
2649
  }
2608
2650
  }
2609
2651
  };
2652
+ /**
2653
+ * @deprecated Use utils.getChoiceForOutput
2654
+ */
2610
2655
  // eslint-disable-next-line class-methods-use-this
2611
2656
  Choices.prototype._getChoiceForOutput = function (choice, keyCode) {
2612
- return {
2613
- id: choice.id,
2614
- highlighted: choice.highlighted,
2615
- labelClass: choice.labelClass,
2616
- labelDescription: choice.labelDescription,
2617
- customProperties: choice.customProperties,
2618
- disabled: choice.disabled,
2619
- active: choice.active,
2620
- label: choice.label,
2621
- placeholder: choice.placeholder,
2622
- value: choice.value,
2623
- groupValue: choice.group ? choice.group.label : undefined,
2624
- element: choice.element,
2625
- keyCode: keyCode,
2626
- };
2657
+ return getChoiceForOutput(choice, keyCode);
2627
2658
  };
2628
2659
  Choices.prototype._triggerChange = function (value) {
2629
2660
  if (value === undefined || value === null) {
@@ -2639,7 +2670,7 @@
2639
2670
  if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {
2640
2671
  return;
2641
2672
  }
2642
- var id = element && parseDataSetId(element.parentElement);
2673
+ var id = element && parseDataSetId(element.closest('[data-id]'));
2643
2674
  var itemToRemove = id && items.find(function (item) { return item.id === id; });
2644
2675
  if (!itemToRemove) {
2645
2676
  return;
@@ -2828,7 +2859,7 @@
2828
2859
  var notice = '';
2829
2860
  if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {
2830
2861
  canAddItem = false;
2831
- notice = resolveNoticeFunction(config.customAddItemText, value);
2862
+ notice = resolveNoticeFunction(config.customAddItemText, value, undefined);
2832
2863
  }
2833
2864
  if (canAddItem) {
2834
2865
  var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });
@@ -2840,12 +2871,12 @@
2840
2871
  }
2841
2872
  if (!config.duplicateItemsAllowed) {
2842
2873
  canAddItem = false;
2843
- notice = resolveNoticeFunction(config.uniqueItemText, value);
2874
+ notice = resolveNoticeFunction(config.uniqueItemText, value, undefined);
2844
2875
  }
2845
2876
  }
2846
2877
  }
2847
2878
  if (canAddItem) {
2848
- notice = resolveNoticeFunction(config.addItemText, value);
2879
+ notice = resolveNoticeFunction(config.addItemText, value, undefined);
2849
2880
  }
2850
2881
  if (notice) {
2851
2882
  this._displayNotice(notice, NoticeTypes.addChoice);
@@ -2896,6 +2927,7 @@
2896
2927
  var documentElement = this._docRoot;
2897
2928
  var outerElement = this.containerOuter.element;
2898
2929
  var inputElement = this.input.element;
2930
+ var passedElement = this.passedElement.element;
2899
2931
  // capture events - can cancel event processing or propagation
2900
2932
  documentElement.addEventListener('touchend', this._onTouchEnd, true);
2901
2933
  outerElement.addEventListener('keydown', this._onKeyDown, true);
@@ -2933,12 +2965,21 @@
2933
2965
  passive: true,
2934
2966
  });
2935
2967
  }
2968
+ if (passedElement.hasAttribute('required')) {
2969
+ passedElement.addEventListener('change', this._onChange, {
2970
+ passive: true,
2971
+ });
2972
+ passedElement.addEventListener('invalid', this._onInvalid, {
2973
+ passive: true,
2974
+ });
2975
+ }
2936
2976
  this.input.addEventListeners();
2937
2977
  };
2938
2978
  Choices.prototype._removeEventListeners = function () {
2939
2979
  var documentElement = this._docRoot;
2940
2980
  var outerElement = this.containerOuter.element;
2941
2981
  var inputElement = this.input.element;
2982
+ var passedElement = this.passedElement.element;
2942
2983
  documentElement.removeEventListener('touchend', this._onTouchEnd, true);
2943
2984
  outerElement.removeEventListener('keydown', this._onKeyDown, true);
2944
2985
  outerElement.removeEventListener('mousedown', this._onMouseDown, true);
@@ -2956,6 +2997,10 @@
2956
2997
  if (inputElement.form) {
2957
2998
  inputElement.form.removeEventListener('reset', this._onFormReset);
2958
2999
  }
3000
+ if (passedElement.hasAttribute('required')) {
3001
+ passedElement.removeEventListener('change', this._onChange);
3002
+ passedElement.removeEventListener('invalid', this._onInvalid);
3003
+ }
2959
3004
  this.input.removeEventListeners();
2960
3005
  };
2961
3006
  Choices.prototype._onKeyDown = function (event) {
@@ -3205,7 +3250,7 @@
3205
3250
  */
3206
3251
  Choices.prototype._onMouseDown = function (event) {
3207
3252
  var target = event.target;
3208
- if (!(target instanceof HTMLElement)) {
3253
+ if (!(target instanceof Element)) {
3209
3254
  return;
3210
3255
  }
3211
3256
  // If we have our mouse down on the scrollbar and are on IE11...
@@ -3314,7 +3359,7 @@
3314
3359
  // Remove the focus state when the past outerContainer was the target
3315
3360
  containerOuter.removeFocusState();
3316
3361
  // Also close the dropdown if search is disabled
3317
- if (!this._canSearch) {
3362
+ if (!this.config.searchEnabled) {
3318
3363
  this.hideDropdown(true);
3319
3364
  }
3320
3365
  }
@@ -3338,13 +3383,19 @@
3338
3383
  }
3339
3384
  });
3340
3385
  };
3341
- Choices.prototype._highlightChoice = function (el) {
3342
- if (el === void 0) { el = null; }
3343
- var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3344
- if (!choices.length) {
3386
+ Choices.prototype._onChange = function (event) {
3387
+ if (!event.target.checkValidity()) {
3345
3388
  return;
3346
3389
  }
3347
- var passedEl = el;
3390
+ this.containerOuter.removeInvalidState();
3391
+ };
3392
+ Choices.prototype._onInvalid = function () {
3393
+ this.containerOuter.addInvalidState();
3394
+ };
3395
+ /**
3396
+ * Removes any highlighted choice options
3397
+ */
3398
+ Choices.prototype._removeHighlightedChoices = function () {
3348
3399
  var highlightedState = this.config.classNames.highlightedState;
3349
3400
  var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));
3350
3401
  // Remove any highlighted choices
@@ -3352,6 +3403,16 @@
3352
3403
  removeClassesFromElement(choice, highlightedState);
3353
3404
  choice.setAttribute('aria-selected', 'false');
3354
3405
  });
3406
+ };
3407
+ Choices.prototype._highlightChoice = function (el) {
3408
+ if (el === void 0) { el = null; }
3409
+ var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3410
+ if (!choices.length) {
3411
+ return;
3412
+ }
3413
+ var passedEl = el;
3414
+ var highlightedState = this.config.classNames.highlightedState;
3415
+ this._removeHighlightedChoices();
3355
3416
  if (passedEl) {
3356
3417
  this._highlightPosition = choices.indexOf(passedEl);
3357
3418
  }
@@ -3392,9 +3453,10 @@
3392
3453
  }
3393
3454
  this._store.dispatch(addItem(item));
3394
3455
  if (withEvents) {
3395
- this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));
3456
+ var eventChoice = getChoiceForOutput(item);
3457
+ this.passedElement.triggerEvent(EventType.addItem, eventChoice);
3396
3458
  if (userTriggered) {
3397
- this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));
3459
+ this.passedElement.triggerEvent(EventType.choice, eventChoice);
3398
3460
  }
3399
3461
  }
3400
3462
  };
@@ -3407,7 +3469,7 @@
3407
3469
  if (notice && notice.type === NoticeTypes.noChoices) {
3408
3470
  this._clearNotice();
3409
3471
  }
3410
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));
3472
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(item));
3411
3473
  };
3412
3474
  Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {
3413
3475
  if (withEvents === void 0) { withEvents = true; }
@@ -3522,25 +3584,25 @@
3522
3584
  containerInner.wrap(passedElement.element);
3523
3585
  // Wrapper inner container with outer container
3524
3586
  containerOuter.wrap(containerInner.element);
3587
+ containerOuter.element.appendChild(containerInner.element);
3588
+ containerOuter.element.appendChild(dropdownElement);
3589
+ containerInner.element.appendChild(this.itemList.element);
3590
+ dropdownElement.appendChild(this.choiceList.element);
3525
3591
  if (this._isSelectOneElement) {
3526
3592
  this.input.placeholder = this.config.searchPlaceholderValue || '';
3593
+ if (this.config.searchEnabled) {
3594
+ dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3595
+ }
3527
3596
  }
3528
3597
  else {
3598
+ if (!this._isSelectMultipleElement || this.config.searchEnabled) {
3599
+ containerInner.element.appendChild(this.input.element);
3600
+ }
3529
3601
  if (this._placeholderValue) {
3530
3602
  this.input.placeholder = this._placeholderValue;
3531
3603
  }
3532
3604
  this.input.setWidth();
3533
3605
  }
3534
- containerOuter.element.appendChild(containerInner.element);
3535
- containerOuter.element.appendChild(dropdownElement);
3536
- containerInner.element.appendChild(this.itemList.element);
3537
- dropdownElement.appendChild(this.choiceList.element);
3538
- if (!this._isSelectOneElement) {
3539
- containerInner.element.appendChild(this.input.element);
3540
- }
3541
- else if (this.config.searchEnabled) {
3542
- dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3543
- }
3544
3606
  this._highlightPosition = 0;
3545
3607
  this._isSearching = false;
3546
3608
  };
@@ -3622,7 +3684,7 @@
3622
3684
  throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it"));
3623
3685
  }
3624
3686
  };
3625
- Choices.version = '11.1.0';
3687
+ Choices.version = '11.2.1';
3626
3688
  return Choices;
3627
3689
  }());
3628
3690