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
@@ -1384,7 +1415,7 @@
1384
1415
  dataset.labelClass = getClassNames(labelClass).join(' ');
1385
1416
  }
1386
1417
  if (labelDescription) {
1387
- dataset.labelDescription = labelDescription;
1418
+ dataset.labelDescription = unwrapStringForRaw(labelDescription);
1388
1419
  }
1389
1420
  if (withCustomProperties && customProperties) {
1390
1421
  if (typeof customProperties === 'string') {
@@ -1491,8 +1522,9 @@
1491
1522
  var removeButton = document.createElement('button');
1492
1523
  removeButton.type = 'button';
1493
1524
  addClassesToElement(removeButton, button);
1494
- setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));
1495
- var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);
1525
+ var eventChoice = getChoiceForOutput(choice);
1526
+ setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value, eventChoice));
1527
+ var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value, eventChoice);
1496
1528
  if (REMOVE_ITEM_LABEL) {
1497
1529
  removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);
1498
1530
  }
@@ -1597,6 +1629,7 @@
1597
1629
  else {
1598
1630
  addClassesToElement(div, itemSelectable);
1599
1631
  div.dataset.choiceSelectable = '';
1632
+ div.setAttribute('aria-selected', choice.selected ? 'true' : 'false');
1600
1633
  }
1601
1634
  return div;
1602
1635
  },
@@ -1766,7 +1799,7 @@
1766
1799
  this.initialised = false;
1767
1800
  this._store = new Store(config);
1768
1801
  this._currentValue = '';
1769
- config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;
1802
+ config.searchEnabled = !isText && config.searchEnabled;
1770
1803
  this._canSearch = config.searchEnabled;
1771
1804
  this._isScrollingOnIe = false;
1772
1805
  this._highlightPosition = 0;
@@ -1806,6 +1839,8 @@
1806
1839
  this._onEscapeKey = this._onEscapeKey.bind(this);
1807
1840
  this._onDirectionKey = this._onDirectionKey.bind(this);
1808
1841
  this._onDeleteKey = this._onDeleteKey.bind(this);
1842
+ this._onChange = this._onChange.bind(this);
1843
+ this._onInvalid = this._onInvalid.bind(this);
1809
1844
  // If element has already been initialised with Choices, fail silently
1810
1845
  if (this.passedElement.isActive) {
1811
1846
  if (!config.silent) {
@@ -1912,7 +1947,7 @@
1912
1947
  }
1913
1948
  this._store.dispatch(highlightItem(choice, true));
1914
1949
  if (runEvent) {
1915
- this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));
1950
+ this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(choice));
1916
1951
  }
1917
1952
  return this;
1918
1953
  };
@@ -1927,7 +1962,7 @@
1927
1962
  }
1928
1963
  this._store.dispatch(highlightItem(choice, false));
1929
1964
  if (runEvent) {
1930
- this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));
1965
+ this.passedElement.triggerEvent(EventType.unhighlightItem, getChoiceForOutput(choice));
1931
1966
  }
1932
1967
  return this;
1933
1968
  };
@@ -1937,7 +1972,7 @@
1937
1972
  _this._store.items.forEach(function (item) {
1938
1973
  if (!item.highlighted) {
1939
1974
  _this._store.dispatch(highlightItem(item, true));
1940
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
1975
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1941
1976
  }
1942
1977
  });
1943
1978
  });
@@ -1949,7 +1984,7 @@
1949
1984
  _this._store.items.forEach(function (item) {
1950
1985
  if (item.highlighted) {
1951
1986
  _this._store.dispatch(highlightItem(item, false));
1952
- _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));
1987
+ _this.passedElement.triggerEvent(EventType.highlightItem, getChoiceForOutput(item));
1953
1988
  }
1954
1989
  });
1955
1990
  });
@@ -2004,6 +2039,11 @@
2004
2039
  _this.input.focus();
2005
2040
  }
2006
2041
  _this.passedElement.triggerEvent(EventType.showDropdown);
2042
+ var activeElement = _this.choiceList.element.querySelector(getClassNamesSelector(_this.config.classNames.selectedState));
2043
+ if (activeElement !== null && !isScrolledIntoView(activeElement, _this.choiceList.element)) {
2044
+ // We use the native scrollIntoView function instead of choiceList.scrollToChildElement to avoid animated scroll.
2045
+ activeElement.scrollIntoView();
2046
+ }
2007
2047
  });
2008
2048
  return this;
2009
2049
  };
@@ -2012,6 +2052,7 @@
2012
2052
  if (!this.dropdown.isActive) {
2013
2053
  return this;
2014
2054
  }
2055
+ this._removeHighlightedChoices();
2015
2056
  requestAnimationFrame(function () {
2016
2057
  _this.dropdown.hide();
2017
2058
  _this.containerOuter.close();
@@ -2024,9 +2065,8 @@
2024
2065
  return this;
2025
2066
  };
2026
2067
  Choices.prototype.getValue = function (valueOnly) {
2027
- var _this = this;
2028
2068
  var values = this._store.items.map(function (item) {
2029
- return (valueOnly ? item.value : _this._getChoiceForOutput(item));
2069
+ return (valueOnly ? item.value : getChoiceForOutput(item));
2030
2070
  });
2031
2071
  return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;
2032
2072
  };
@@ -2284,7 +2324,7 @@
2284
2324
  // @todo integrate with Store
2285
2325
  this._searcher.reset();
2286
2326
  if (choice.selected) {
2287
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));
2327
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(choice));
2288
2328
  }
2289
2329
  return this;
2290
2330
  };
@@ -2367,13 +2407,7 @@
2367
2407
  }
2368
2408
  var _a = this, config = _a.config, isSearching = _a._isSearching;
2369
2409
  var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;
2370
- var renderLimit = 0;
2371
- if (isSearching && config.searchResultLimit > 0) {
2372
- renderLimit = config.searchResultLimit;
2373
- }
2374
- else if (config.renderChoiceLimit > 0) {
2375
- renderLimit = config.renderChoiceLimit;
2376
- }
2410
+ var renderLimit = isSearching ? config.searchResultLimit : config.renderChoiceLimit;
2377
2411
  if (this._isSelectElement) {
2378
2412
  var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });
2379
2413
  if (backingOptions.length) {
@@ -2383,11 +2417,16 @@
2383
2417
  var fragment = document.createDocumentFragment();
2384
2418
  var renderableChoices = function (choices) {
2385
2419
  return choices.filter(function (choice) {
2386
- return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);
2420
+ return !choice.placeholder &&
2421
+ (isSearching
2422
+ ? (config.searchRenderSelectedChoices || !choice.selected) && !!choice.rank
2423
+ : config.renderSelectedChoices || !choice.selected);
2387
2424
  });
2388
2425
  };
2426
+ var showLabel = config.appendGroupInSearch && isSearching;
2389
2427
  var selectableChoices = false;
2390
- var renderChoices = function (choices, withinGroup, groupLabel) {
2428
+ var highlightedEl = null;
2429
+ var renderChoices = function (choices, withinGroup) {
2391
2430
  if (isSearching) {
2392
2431
  // sortByRank is used to ensure stable sorting, as scores are non-unique
2393
2432
  // this additionally ensures fuseOptions.sortFn is not ignored
@@ -2397,16 +2436,20 @@
2397
2436
  choices.sort(config.sorter);
2398
2437
  }
2399
2438
  var choiceLimit = choices.length;
2400
- choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2439
+ choiceLimit = !withinGroup && renderLimit > 0 && choiceLimit > renderLimit ? renderLimit : choiceLimit;
2401
2440
  choiceLimit--;
2402
2441
  choices.every(function (choice, index) {
2403
2442
  // choiceEl being empty signals the contents has probably significantly changed
2404
- var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);
2443
+ var dropdownItem = choice.choiceEl ||
2444
+ _this._templates.choice(config, choice, config.itemSelectText, showLabel && choice.group ? choice.group.label : undefined);
2405
2445
  choice.choiceEl = dropdownItem;
2406
2446
  fragment.appendChild(dropdownItem);
2407
2447
  if (isSearching || !choice.selected) {
2408
2448
  selectableChoices = true;
2409
2449
  }
2450
+ else if (!highlightedEl) {
2451
+ highlightedEl = dropdownItem;
2452
+ }
2410
2453
  return index < choiceLimit;
2411
2454
  });
2412
2455
  };
@@ -2416,7 +2459,7 @@
2416
2459
  }
2417
2460
  if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {
2418
2461
  // If we have a placeholder choice along with groups
2419
- renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);
2462
+ renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false);
2420
2463
  }
2421
2464
  // If we have grouped options
2422
2465
  if (activeGroups.length && !isSearching) {
@@ -2425,7 +2468,7 @@
2425
2468
  }
2426
2469
  // render Choices without group first, regardless of sort, otherwise they won't be distinguishable
2427
2470
  // from the last group
2428
- renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);
2471
+ renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false);
2429
2472
  activeGroups.forEach(function (group) {
2430
2473
  var groupChoices = renderableChoices(group.choices);
2431
2474
  if (groupChoices.length) {
@@ -2435,12 +2478,12 @@
2435
2478
  dropdownGroup.remove();
2436
2479
  fragment.appendChild(dropdownGroup);
2437
2480
  }
2438
- renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);
2481
+ renderChoices(groupChoices, true);
2439
2482
  }
2440
2483
  });
2441
2484
  }
2442
2485
  else {
2443
- renderChoices(renderableChoices(activeChoices), false, undefined);
2486
+ renderChoices(renderableChoices(activeChoices), false);
2444
2487
  }
2445
2488
  }
2446
2489
  if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {
@@ -2454,9 +2497,7 @@
2454
2497
  }
2455
2498
  this._renderNotice(fragment);
2456
2499
  this.choiceList.element.replaceChildren(fragment);
2457
- if (selectableChoices) {
2458
- this._highlightChoice();
2459
- }
2500
+ this._highlightChoice(highlightedEl);
2460
2501
  };
2461
2502
  Choices.prototype._renderItems = function () {
2462
2503
  var _this = this;
@@ -2566,23 +2607,12 @@
2566
2607
  }
2567
2608
  }
2568
2609
  };
2610
+ /**
2611
+ * @deprecated Use utils.getChoiceForOutput
2612
+ */
2569
2613
  // eslint-disable-next-line class-methods-use-this
2570
2614
  Choices.prototype._getChoiceForOutput = function (choice, keyCode) {
2571
- return {
2572
- id: choice.id,
2573
- highlighted: choice.highlighted,
2574
- labelClass: choice.labelClass,
2575
- labelDescription: choice.labelDescription,
2576
- customProperties: choice.customProperties,
2577
- disabled: choice.disabled,
2578
- active: choice.active,
2579
- label: choice.label,
2580
- placeholder: choice.placeholder,
2581
- value: choice.value,
2582
- groupValue: choice.group ? choice.group.label : undefined,
2583
- element: choice.element,
2584
- keyCode: keyCode,
2585
- };
2615
+ return getChoiceForOutput(choice, keyCode);
2586
2616
  };
2587
2617
  Choices.prototype._triggerChange = function (value) {
2588
2618
  if (value === undefined || value === null) {
@@ -2598,7 +2628,7 @@
2598
2628
  if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {
2599
2629
  return;
2600
2630
  }
2601
- var id = element && parseDataSetId(element.parentElement);
2631
+ var id = element && parseDataSetId(element.closest('[data-id]'));
2602
2632
  var itemToRemove = id && items.find(function (item) { return item.id === id; });
2603
2633
  if (!itemToRemove) {
2604
2634
  return;
@@ -2787,7 +2817,7 @@
2787
2817
  var notice = '';
2788
2818
  if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {
2789
2819
  canAddItem = false;
2790
- notice = resolveNoticeFunction(config.customAddItemText, value);
2820
+ notice = resolveNoticeFunction(config.customAddItemText, value, undefined);
2791
2821
  }
2792
2822
  if (canAddItem) {
2793
2823
  var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });
@@ -2799,12 +2829,12 @@
2799
2829
  }
2800
2830
  if (!config.duplicateItemsAllowed) {
2801
2831
  canAddItem = false;
2802
- notice = resolveNoticeFunction(config.uniqueItemText, value);
2832
+ notice = resolveNoticeFunction(config.uniqueItemText, value, undefined);
2803
2833
  }
2804
2834
  }
2805
2835
  }
2806
2836
  if (canAddItem) {
2807
- notice = resolveNoticeFunction(config.addItemText, value);
2837
+ notice = resolveNoticeFunction(config.addItemText, value, undefined);
2808
2838
  }
2809
2839
  if (notice) {
2810
2840
  this._displayNotice(notice, NoticeTypes.addChoice);
@@ -2855,6 +2885,7 @@
2855
2885
  var documentElement = this._docRoot;
2856
2886
  var outerElement = this.containerOuter.element;
2857
2887
  var inputElement = this.input.element;
2888
+ var passedElement = this.passedElement.element;
2858
2889
  // capture events - can cancel event processing or propagation
2859
2890
  documentElement.addEventListener('touchend', this._onTouchEnd, true);
2860
2891
  outerElement.addEventListener('keydown', this._onKeyDown, true);
@@ -2892,12 +2923,21 @@
2892
2923
  passive: true,
2893
2924
  });
2894
2925
  }
2926
+ if (passedElement.hasAttribute('required')) {
2927
+ passedElement.addEventListener('change', this._onChange, {
2928
+ passive: true,
2929
+ });
2930
+ passedElement.addEventListener('invalid', this._onInvalid, {
2931
+ passive: true,
2932
+ });
2933
+ }
2895
2934
  this.input.addEventListeners();
2896
2935
  };
2897
2936
  Choices.prototype._removeEventListeners = function () {
2898
2937
  var documentElement = this._docRoot;
2899
2938
  var outerElement = this.containerOuter.element;
2900
2939
  var inputElement = this.input.element;
2940
+ var passedElement = this.passedElement.element;
2901
2941
  documentElement.removeEventListener('touchend', this._onTouchEnd, true);
2902
2942
  outerElement.removeEventListener('keydown', this._onKeyDown, true);
2903
2943
  outerElement.removeEventListener('mousedown', this._onMouseDown, true);
@@ -2915,6 +2955,10 @@
2915
2955
  if (inputElement.form) {
2916
2956
  inputElement.form.removeEventListener('reset', this._onFormReset);
2917
2957
  }
2958
+ if (passedElement.hasAttribute('required')) {
2959
+ passedElement.removeEventListener('change', this._onChange);
2960
+ passedElement.removeEventListener('invalid', this._onInvalid);
2961
+ }
2918
2962
  this.input.removeEventListeners();
2919
2963
  };
2920
2964
  Choices.prototype._onKeyDown = function (event) {
@@ -3164,7 +3208,7 @@
3164
3208
  */
3165
3209
  Choices.prototype._onMouseDown = function (event) {
3166
3210
  var target = event.target;
3167
- if (!(target instanceof HTMLElement)) {
3211
+ if (!(target instanceof Element)) {
3168
3212
  return;
3169
3213
  }
3170
3214
  // If we have our mouse down on the scrollbar and are on IE11...
@@ -3273,7 +3317,7 @@
3273
3317
  // Remove the focus state when the past outerContainer was the target
3274
3318
  containerOuter.removeFocusState();
3275
3319
  // Also close the dropdown if search is disabled
3276
- if (!this._canSearch) {
3320
+ if (!this.config.searchEnabled) {
3277
3321
  this.hideDropdown(true);
3278
3322
  }
3279
3323
  }
@@ -3297,13 +3341,19 @@
3297
3341
  }
3298
3342
  });
3299
3343
  };
3300
- Choices.prototype._highlightChoice = function (el) {
3301
- if (el === void 0) { el = null; }
3302
- var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3303
- if (!choices.length) {
3344
+ Choices.prototype._onChange = function (event) {
3345
+ if (!event.target.checkValidity()) {
3304
3346
  return;
3305
3347
  }
3306
- var passedEl = el;
3348
+ this.containerOuter.removeInvalidState();
3349
+ };
3350
+ Choices.prototype._onInvalid = function () {
3351
+ this.containerOuter.addInvalidState();
3352
+ };
3353
+ /**
3354
+ * Removes any highlighted choice options
3355
+ */
3356
+ Choices.prototype._removeHighlightedChoices = function () {
3307
3357
  var highlightedState = this.config.classNames.highlightedState;
3308
3358
  var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));
3309
3359
  // Remove any highlighted choices
@@ -3311,6 +3361,16 @@
3311
3361
  removeClassesFromElement(choice, highlightedState);
3312
3362
  choice.setAttribute('aria-selected', 'false');
3313
3363
  });
3364
+ };
3365
+ Choices.prototype._highlightChoice = function (el) {
3366
+ if (el === void 0) { el = null; }
3367
+ var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));
3368
+ if (!choices.length) {
3369
+ return;
3370
+ }
3371
+ var passedEl = el;
3372
+ var highlightedState = this.config.classNames.highlightedState;
3373
+ this._removeHighlightedChoices();
3314
3374
  if (passedEl) {
3315
3375
  this._highlightPosition = choices.indexOf(passedEl);
3316
3376
  }
@@ -3351,9 +3411,10 @@
3351
3411
  }
3352
3412
  this._store.dispatch(addItem(item));
3353
3413
  if (withEvents) {
3354
- this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));
3414
+ var eventChoice = getChoiceForOutput(item);
3415
+ this.passedElement.triggerEvent(EventType.addItem, eventChoice);
3355
3416
  if (userTriggered) {
3356
- this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));
3417
+ this.passedElement.triggerEvent(EventType.choice, eventChoice);
3357
3418
  }
3358
3419
  }
3359
3420
  };
@@ -3366,7 +3427,7 @@
3366
3427
  if (notice && notice.type === NoticeTypes.noChoices) {
3367
3428
  this._clearNotice();
3368
3429
  }
3369
- this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));
3430
+ this.passedElement.triggerEvent(EventType.removeItem, getChoiceForOutput(item));
3370
3431
  };
3371
3432
  Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {
3372
3433
  if (withEvents === void 0) { withEvents = true; }
@@ -3481,25 +3542,25 @@
3481
3542
  containerInner.wrap(passedElement.element);
3482
3543
  // Wrapper inner container with outer container
3483
3544
  containerOuter.wrap(containerInner.element);
3545
+ containerOuter.element.appendChild(containerInner.element);
3546
+ containerOuter.element.appendChild(dropdownElement);
3547
+ containerInner.element.appendChild(this.itemList.element);
3548
+ dropdownElement.appendChild(this.choiceList.element);
3484
3549
  if (this._isSelectOneElement) {
3485
3550
  this.input.placeholder = this.config.searchPlaceholderValue || '';
3551
+ if (this.config.searchEnabled) {
3552
+ dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3553
+ }
3486
3554
  }
3487
3555
  else {
3556
+ if (!this._isSelectMultipleElement || this.config.searchEnabled) {
3557
+ containerInner.element.appendChild(this.input.element);
3558
+ }
3488
3559
  if (this._placeholderValue) {
3489
3560
  this.input.placeholder = this._placeholderValue;
3490
3561
  }
3491
3562
  this.input.setWidth();
3492
3563
  }
3493
- containerOuter.element.appendChild(containerInner.element);
3494
- containerOuter.element.appendChild(dropdownElement);
3495
- containerInner.element.appendChild(this.itemList.element);
3496
- dropdownElement.appendChild(this.choiceList.element);
3497
- if (!this._isSelectOneElement) {
3498
- containerInner.element.appendChild(this.input.element);
3499
- }
3500
- else if (this.config.searchEnabled) {
3501
- dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);
3502
- }
3503
3564
  this._highlightPosition = 0;
3504
3565
  this._isSearching = false;
3505
3566
  };
@@ -3581,7 +3642,7 @@
3581
3642
  throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it"));
3582
3643
  }
3583
3644
  };
3584
- Choices.version = '11.1.0';
3645
+ Choices.version = '11.2.1';
3585
3646
  return Choices;
3586
3647
  }());
3587
3648