@arc-ui/components 13.0.0 → 13.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 (176) hide show
  1. package/lib/Alert/styles.css +1 -1
  2. package/lib/Align/styles.css +1 -1
  3. package/lib/AppButton/styles.css +1 -1
  4. package/lib/Avatar/styles.css +1 -1
  5. package/lib/AvatarGroup/styles.css +1 -1
  6. package/lib/Badge/styles.css +1 -1
  7. package/lib/Banner/Banner.cjs +7 -3
  8. package/lib/Banner/Banner.mjs +7 -3
  9. package/lib/Box/styles.css +1 -1
  10. package/lib/BrandLogo/styles.css +1 -1
  11. package/lib/Breadcrumbs/styles.css +1 -1
  12. package/lib/Button/styles.css +1 -1
  13. package/lib/ButtonGroup/styles.css +1 -1
  14. package/lib/ButtonV2/styles.css +1 -1
  15. package/lib/Calendar/Calendar.cjs +2 -2
  16. package/lib/Calendar/Calendar.mjs +2 -2
  17. package/lib/Calendar/styles.css +1 -1
  18. package/lib/CardFooter/styles.css +1 -1
  19. package/lib/CardHeading/styles.css +1 -1
  20. package/lib/Carousel/Carousel.cjs +26 -14
  21. package/lib/Carousel/Carousel.mjs +26 -14
  22. package/lib/Carousel/styles.css +1 -1
  23. package/lib/Checkbox/styles.css +1 -1
  24. package/lib/CheckboxIcon/styles.css +1 -1
  25. package/lib/ClientSideVisible/ClientSideVisible.cjs +1 -0
  26. package/lib/ClientSideVisible/ClientSideVisible.mjs +1 -0
  27. package/lib/Columns/styles.css +1 -1
  28. package/lib/ComboBox/ComboBox.cjs +530 -136
  29. package/lib/ComboBox/ComboBox.mjs +530 -136
  30. package/lib/ComboBox/styles.css +1 -1
  31. package/lib/ConditionalWrapper/ConditionalWrapper.cjs +1 -0
  32. package/lib/ConditionalWrapper/ConditionalWrapper.mjs +1 -0
  33. package/lib/ContentSwitcher/styles.css +1 -1
  34. package/lib/ContentSwitcherDropdown/styles.css +1 -1
  35. package/lib/DatePicker/DatePicker.cjs +3 -3
  36. package/lib/DatePicker/DatePicker.mjs +3 -3
  37. package/lib/DatePicker/styles.css +1 -1
  38. package/lib/Disclosure/styles.css +1 -1
  39. package/lib/DisclosureMini/styles.css +1 -1
  40. package/lib/Download/styles.css +1 -1
  41. package/lib/Drawer/styles.css +1 -1
  42. package/lib/Elevation/styles.css +1 -1
  43. package/lib/Filter/styles.css +1 -1
  44. package/lib/FormControl/styles.css +1 -1
  45. package/lib/GhostedHeroBanner/styles.css +1 -1
  46. package/lib/GradientPageBackground/GradientPageBackground.cjs +2 -2
  47. package/lib/GradientPageBackground/GradientPageBackground.mjs +2 -2
  48. package/lib/GradientPageBackground/styles.css +1 -1
  49. package/lib/Grid/Grid.cjs +1 -0
  50. package/lib/Grid/Grid.mjs +1 -0
  51. package/lib/Grid/styles.css +1 -1
  52. package/lib/Group/styles.css +1 -1
  53. package/lib/Heading/styles.css +1 -1
  54. package/lib/HeroBanner/HeroBanner.cjs +7 -3
  55. package/lib/HeroBanner/HeroBanner.mjs +7 -3
  56. package/lib/HeroBanner/styles.css +1 -1
  57. package/lib/HeroButton/styles.css +1 -1
  58. package/lib/Hidden/styles.css +1 -1
  59. package/lib/HorizontalCard/styles.css +1 -1
  60. package/lib/Icon/styles.css +1 -1
  61. package/lib/Image/styles.css +1 -1
  62. package/lib/ImpactCard/ImpactCard.cjs +28 -15
  63. package/lib/ImpactCard/ImpactCard.mjs +29 -16
  64. package/lib/ImpactCard/styles.css +1 -1
  65. package/lib/InformationCard/InformationCard.cjs +57 -33
  66. package/lib/InformationCard/InformationCard.mjs +59 -35
  67. package/lib/InformationCard/styles.css +1 -1
  68. package/lib/Link/styles.css +1 -1
  69. package/lib/Markup/styles.css +1 -1
  70. package/lib/MediaCard/MediaCard.cjs +40 -21
  71. package/lib/MediaCard/MediaCard.mjs +41 -22
  72. package/lib/MediaCard/styles.css +1 -1
  73. package/lib/Menu/styles.css +1 -1
  74. package/lib/Modal/styles.css +1 -1
  75. package/lib/NavigationHeader/NavigationHeader.cjs +2764 -472
  76. package/lib/NavigationHeader/NavigationHeader.mjs +2707 -436
  77. package/lib/NavigationHeader/styles.css +1 -1
  78. package/lib/Pagination/styles.css +1 -1
  79. package/lib/PaginationSimple/styles.css +1 -1
  80. package/lib/Popover/Popover.cjs +1 -1
  81. package/lib/Popover/Popover.mjs +1 -1
  82. package/lib/Popover/styles.css +1 -1
  83. package/lib/Poster/styles.css +1 -1
  84. package/lib/ProgressBar/styles.css +1 -1
  85. package/lib/ProgressStepper/styles.css +1 -1
  86. package/lib/ProgressStepperOverflow/styles.css +1 -1
  87. package/lib/RadioCardGroup/styles.css +1 -1
  88. package/lib/RadioGroup/RadioGroup.cjs +2 -1
  89. package/lib/RadioGroup/RadioGroup.mjs +2 -1
  90. package/lib/RadioGroup/styles.css +1 -1
  91. package/lib/Rule/styles.css +1 -1
  92. package/lib/ScrollToTop/styles.css +1 -1
  93. package/lib/Section/styles.css +1 -1
  94. package/lib/Select/styles.css +1 -1
  95. package/lib/SemanticButton/SemanticButton.cjs +10 -0
  96. package/lib/SemanticButton/SemanticButton.mjs +4 -0
  97. package/lib/SemanticButton/styles.css +1 -0
  98. package/lib/SemanticHeading/styles.css +1 -1
  99. package/lib/SemanticLink/SemanticLink.cjs +10 -0
  100. package/lib/SemanticLink/SemanticLink.mjs +4 -0
  101. package/lib/SemanticLink/styles.css +1 -0
  102. package/lib/SiteFooter/styles.css +1 -1
  103. package/lib/SiteFooterV2/SiteFooterV2.cjs +3 -2
  104. package/lib/SiteFooterV2/SiteFooterV2.mjs +3 -2
  105. package/lib/SiteFooterV2/styles.css +1 -1
  106. package/lib/SiteHeaderV2/SiteHeaderV2.cjs +1 -1
  107. package/lib/SiteHeaderV2/SiteHeaderV2.mjs +1 -1
  108. package/lib/SiteHeaderV2/styles.css +1 -1
  109. package/lib/Skeleton/styles.css +1 -1
  110. package/lib/SkipLink/SkipLink.cjs +1 -0
  111. package/lib/SkipLink/SkipLink.mjs +1 -0
  112. package/lib/SkipLink/styles.css +1 -1
  113. package/lib/Spacing/Spacing.cjs +38 -0
  114. package/lib/Spacing/Spacing.mjs +36 -0
  115. package/lib/Spacing/styles.css +1 -0
  116. package/lib/Spinner/styles.css +1 -1
  117. package/lib/Surface/styles.css +1 -1
  118. package/lib/Switch/styles.css +1 -1
  119. package/lib/TabbedBanner/TabbedBanner.cjs +5 -3
  120. package/lib/TabbedBanner/TabbedBanner.mjs +5 -3
  121. package/lib/TabbedBanner/styles.css +1 -1
  122. package/lib/Tabs/Tabs.cjs +57 -25
  123. package/lib/Tabs/Tabs.mjs +57 -25
  124. package/lib/Tabs/styles.css +1 -1
  125. package/lib/Tag/styles.css +1 -1
  126. package/lib/TemplateBanner/TemplateBanner.cjs +5 -1
  127. package/lib/TemplateBanner/TemplateBanner.mjs +5 -1
  128. package/lib/TemplateBanner/styles.css +1 -1
  129. package/lib/Text/styles.css +1 -1
  130. package/lib/TextArea/styles.css +1 -1
  131. package/lib/TextInput/TextInput.cjs +1 -1
  132. package/lib/TextInput/TextInput.mjs +1 -1
  133. package/lib/TextInput/styles.css +1 -1
  134. package/lib/Theme/Theme.cjs +1 -1
  135. package/lib/Theme/Theme.mjs +1 -1
  136. package/lib/Theme/styles.css +1 -1
  137. package/lib/ThemeIcon/styles.css +1 -1
  138. package/lib/ThumbnailSignpost/styles.css +1 -1
  139. package/lib/Toast/styles.css +1 -1
  140. package/lib/Tooltip/styles.css +1 -1
  141. package/lib/Truncate/styles.css +1 -1
  142. package/lib/TypographyCard/TypographyCard.cjs +38 -14
  143. package/lib/TypographyCard/TypographyCard.mjs +39 -15
  144. package/lib/TypographyCard/styles.css +1 -1
  145. package/lib/UniversalHeader/UniversalHeader.cjs +10 -8
  146. package/lib/UniversalHeader/UniversalHeader.mjs +10 -8
  147. package/lib/UniversalHeader/styles.css +1 -1
  148. package/lib/VerticalSpace/styles.css +1 -1
  149. package/lib/VideoPlayer/styles.css +1 -1
  150. package/lib/Visible/styles.css +1 -1
  151. package/lib/VisuallyHidden/styles.css +1 -1
  152. package/lib/_shared/cjs/{Calendar-CdLn9iv6.cjs → Calendar-B-DmNni2.cjs} +1 -1
  153. package/lib/_shared/cjs/{Popover-BtvRErpC.cjs → Popover-BxuQPltF.cjs} +2 -2
  154. package/lib/_shared/cjs/SemanticButton-Be0gsNLA.cjs +16 -0
  155. package/lib/_shared/cjs/SemanticLink-DYO9HLGa.cjs +16 -0
  156. package/lib/_shared/cjs/{TemplateBanner-DyXBKuMw.cjs → TemplateBanner-DfzDwiVT.cjs} +35 -5
  157. package/lib/_shared/cjs/{TextInput-C_K2PLf5.cjs → TextInput-CLkhL2KT.cjs} +39 -6
  158. package/lib/_shared/cjs/{arc-breakpoints-uADxN-b4.cjs → arc-breakpoints-C3HREhvT.cjs} +1 -1
  159. package/lib/_shared/cjs/{index.es-BAsay4oe.cjs → index.es-D5DdMrn2.cjs} +1 -1
  160. package/lib/_shared/esm/{Calendar-CzFIMyD1.mjs → Calendar-CfEBiAjy.mjs} +1 -1
  161. package/lib/_shared/esm/{Popover-DRQSgAog.mjs → Popover-Pjtmu_TN.mjs} +2 -2
  162. package/lib/_shared/esm/SemanticButton-NGAMAw3m.mjs +14 -0
  163. package/lib/_shared/esm/SemanticLink-DfJjaHk2.mjs +14 -0
  164. package/lib/_shared/esm/{TemplateBanner-BPzuH5bz.mjs → TemplateBanner-oQjgkrBQ.mjs} +36 -6
  165. package/lib/_shared/esm/{TextInput-BCvKXfM_.mjs → TextInput-WczTCUvp.mjs} +40 -7
  166. package/lib/_shared/esm/{arc-breakpoints-ChQgbftE.mjs → arc-breakpoints-ANMn37k9.mjs} +1 -1
  167. package/lib/_shared/esm/{index.es-99J0r2va.mjs → index.es-Du5Lyvbp.mjs} +2 -2
  168. package/lib/index.cjs +9958 -7073
  169. package/lib/index.cjs.map +1 -1
  170. package/lib/index.d.cts +560 -203
  171. package/lib/index.d.mts +560 -203
  172. package/lib/index.js.map +1 -1
  173. package/lib/index.mjs +16949 -14068
  174. package/lib/index.mjs.map +1 -1
  175. package/lib/styles.css +6 -2
  176. package/package.json +9 -8
@@ -1,123 +1,223 @@
1
1
  'use client';
2
2
  import { b as __spreadArray, a as __assign, _ as __rest } from '../_shared/esm/tslib.es6-w7hdJ3oZ.mjs';
3
- import React__default, { useId, useRef, useReducer } from 'react';
4
- import { R as Root2, A as Anchor2, P as Portal, C as Content2 } from '../_shared/esm/index-Dd3yZ_Kk.mjs';
3
+ import React__default, { useId, useContext, useRef, useReducer, useEffect } from 'react';
5
4
  import { c as classNames } from '../_shared/esm/index-5C0-U8cc.mjs';
5
+ import { R as Root2, A as Anchor2, P as Portal, C as Content2 } from '../_shared/esm/index-Dd3yZ_Kk.mjs';
6
6
  import { f as filterAttrs } from '../_shared/esm/filter-attrs-v_SweZXP.mjs';
7
+ import { s as suffixModifier } from '../_shared/esm/suffix-modifier-B_pO0UkF.mjs';
7
8
  import { u as useAriaDescribedby, F as FormControl } from '../_shared/esm/FormControl-DopDD_nC.mjs';
8
9
  import { e as useThemeElement } from '../_shared/esm/index-DkAfUbDx.mjs';
9
- import { B as Box } from '../_shared/esm/Box-C8iK8x5c.mjs';
10
10
  import { I as Icon } from '../_shared/esm/Icon-CCUbr_AO.mjs';
11
+ import { C as Context } from '../_shared/esm/Surface-C69KVzkY.mjs';
11
12
  import { T as ThemeIcon } from '../_shared/esm/ThemeIcon-B0n6cKRb.mjs';
13
+ import { T as Tooltip } from '../_shared/esm/Tooltip-DY8nS1to.mjs';
14
+ import { V as VerticalSpace } from '../_shared/esm/VerticalSpace-BLWB02I7.mjs';
15
+ import { T as Text } from '../_shared/esm/Text-BAzOkkzN.mjs';
16
+ import { R as Rule } from '../_shared/esm/Rule-Bz3QPezk.mjs';
12
17
  import '../_shared/esm/Combination-BW0YAEZD.mjs';
13
18
  import 'react/jsx-runtime';
14
19
  import 'react-dom';
15
20
  import '../_shared/esm/index-DNvlT7G_.mjs';
16
21
  import '../_shared/esm/index-Cgsjp3NL.mjs';
17
22
  import '../_shared/esm/index-BMmvMegf.mjs';
18
- import '../_shared/esm/Surface-C69KVzkY.mjs';
19
23
  import '../_shared/esm/index-Spae4j7j.mjs';
20
24
  import '../_shared/esm/DisclosureMini-DeQZyvDN.mjs';
21
- import '../_shared/esm/Text-BAzOkkzN.mjs';
22
- import '../_shared/esm/suffix-modifier-B_pO0UkF.mjs';
23
25
  import '../_shared/esm/VisuallyHidden-aSQ4RA1o.mjs';
24
26
 
25
- /**
26
- * Do not edit directly
27
- * Generated file
28
- */
29
-
30
- const BtIconChevronDown2Px =
31
- "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3e%3cpath fill='currentColor' d='M15.993 23.914 2.294 10.207a1 1 0 1 1 1.414-1.414l12.285 12.293L28.292 8.793a1 1 0 1 1 1.414 1.414Z'/%3e%3c/svg%3e";
27
+ var convertOptionsToObjects = function (options) {
28
+ return options.map(function (option) { return ({
29
+ isCustom: false,
30
+ text: option,
31
+ }); });
32
+ };
32
33
 
33
34
  var filterOptions = function (options, value) {
34
- return options.filter(function (option) {
35
+ return options
36
+ .filter(function (option) {
35
37
  return value ? option.toLowerCase().includes(value.toLowerCase()) : true;
36
- });
38
+ })
39
+ .map(function (option) { return ({ text: option, isCustom: false }); });
40
+ };
41
+
42
+ var findOptionIndex = function (options, searchOption) { return options.findIndex(function (option) { return option.text === searchOption.text; }); };
43
+
44
+ var getClosestMatchingOptionIndex = function (options, filteredOptions) {
45
+ return options.length && filteredOptions.length
46
+ ? options.findIndex(function (option) { return option.text === filteredOptions[0].text; })
47
+ : 0;
48
+ };
49
+
50
+ var isOptionValueMatch = function (option, value) {
51
+ return option.text.toLowerCase() === value.toLowerCase();
52
+ };
53
+
54
+ var getMatchingOption = function (options, value) {
55
+ return options.find(function (option) { return isOptionValueMatch(option, value); });
56
+ };
57
+
58
+ var getKeydownOptionToHighlight = function (_a) {
59
+ var options = _a.options, isNext = _a.isNext, highlightedOptionIndex = _a.highlightedOptionIndex;
60
+ var currentHighlightIndex = highlightedOptionIndex !== null && highlightedOptionIndex !== void 0 ? highlightedOptionIndex : -1;
61
+ var isAtBoundary = isNext
62
+ ? currentHighlightIndex === options.length - 1
63
+ : currentHighlightIndex <= 0;
64
+ var boundaryIndex = isNext ? 0 : options.length - 1;
65
+ var nextOptionIndex = isNext
66
+ ? currentHighlightIndex + 1
67
+ : currentHighlightIndex - 1;
68
+ return isAtBoundary ? boundaryIndex : nextOptionIndex;
69
+ };
70
+
71
+ var multiSelectLimitReached = function (newSelectedOptions, multiSelectLimit) { return (multiSelectLimit ? newSelectedOptions.length >= multiSelectLimit : false); };
72
+
73
+ var convertOptionsToText = function (options) {
74
+ return options.map(function (option) { return option.text; });
75
+ };
76
+
77
+ var canAddNewMultiSelectOptions = function (newSelectedOptions, multiSelectLimit) {
78
+ return !multiSelectLimit ||
79
+ (multiSelectLimit && newSelectedOptions.length <= multiSelectLimit);
37
80
  };
81
+
38
82
  var getSelectedOptions = function (option, selectedOptions) {
39
- return selectedOptions.indexOf(option) !== -1
40
- ? selectedOptions.filter(function (selectedOption) { return selectedOption !== option; })
83
+ var isOptionCurrentlySelected = getMatchingOption(selectedOptions, option.text);
84
+ return isOptionCurrentlySelected
85
+ ? selectedOptions.filter(function (selectedOption) { return !isOptionValueMatch(selectedOption, option.text); })
41
86
  : __spreadArray(__spreadArray([], selectedOptions, true), [option], false);
42
87
  };
43
- var findOptionIndex = function (options, searchOption) {
44
- return options.findIndex(function (option) { return option === searchOption; });
45
- };
46
- var isSelected = function (option, selectedOptions) {
47
- return selectedOptions.some(function (selectedOption) { return option === selectedOption; });
88
+
89
+ var getNewMultiSelectOptions = function (selectedOption, selectedOptions, multiSelectLimit) {
90
+ var newSelectedOptions = getSelectedOptions(selectedOption, selectedOptions);
91
+ var limitReached = multiSelectLimitReached(newSelectedOptions, multiSelectLimit);
92
+ var canAddNewOptions = canAddNewMultiSelectOptions(newSelectedOptions, multiSelectLimit);
93
+ return {
94
+ newOptions: canAddNewOptions ? newSelectedOptions : selectedOptions,
95
+ limitReached: limitReached,
96
+ };
48
97
  };
49
98
 
50
99
  var reducer = function (initialOptions) {
51
100
  return function (state, action) {
101
+ var _a;
52
102
  switch (action.type) {
53
103
  case "OPEN": {
54
- var isMultiSelectable = action.payload.isMultiSelectable;
55
- var selectedOptions = state.selectedOptions, options = state.options;
56
- return __assign(__assign({}, state), { isExpanded: true, highlightedOptionIndex: isMultiSelectable && selectedOptions.length
57
- ? findOptionIndex(options, selectedOptions[selectedOptions.length - 1])
58
- : 0 });
104
+ return __assign(__assign({}, state), { isExpanded: true, highlightedOptionIndex: 0 });
105
+ }
106
+ case "CLOSE_MENU": {
107
+ return __assign(__assign({}, state), { showAllTags: false, isExpanded: false, highlightedOptionIndex: undefined });
108
+ }
109
+ case "CLEAR": {
110
+ return __assign(__assign({}, state), { value: "", singleSelectedOption: action.payload.isCustomEntryAllowed
111
+ ? { isCustom: false, text: "" }
112
+ : state.singleSelectedOption, options: convertOptionsToObjects(initialOptions), onChangeValue: action.payload.isMultiSelectable
113
+ ? convertOptionsToText(state.selectedOptions)
114
+ : "" });
115
+ }
116
+ case "SHOW_ALL_TAGS": {
117
+ return __assign(__assign({}, state), { showAllTags: true });
118
+ }
119
+ case "EXIT_INPUT": {
120
+ var _b = action.payload, isMultiSelectable = _b.isMultiSelectable, isCustomEntryAllowed = _b.isCustomEntryAllowed;
121
+ var matchingOption = getMatchingOption(state.options, state.value);
122
+ var allOptions = convertOptionsToObjects(initialOptions);
123
+ var isCustomEntrySingleSelect = !isMultiSelectable && isCustomEntryAllowed;
124
+ var isConstrainedSingleSelect = !isMultiSelectable && !isCustomEntryAllowed;
125
+ var commonState = __assign(__assign({}, state), { options: allOptions, showAllTags: false, isExpanded: false, highlightedOptionIndex: undefined });
126
+ if (!isMultiSelectable && matchingOption) {
127
+ return __assign(__assign({}, commonState), { singleSelectedOption: matchingOption, value: matchingOption.text, onChangeValue: matchingOption.text });
128
+ }
129
+ if (isCustomEntrySingleSelect && !matchingOption) {
130
+ return __assign(__assign({}, commonState), { value: state.value, onChangeValue: state.value });
131
+ }
132
+ if (isConstrainedSingleSelect) {
133
+ var newValue = ((_a = state.singleSelectedOption) === null || _a === void 0 ? void 0 : _a.text) || "";
134
+ return __assign(__assign({}, commonState), { value: newValue, onChangeValue: newValue });
135
+ }
136
+ return __assign(__assign({}, commonState), { value: "", onChangeValue: isMultiSelectable
137
+ ? convertOptionsToText(state.selectedOptions)
138
+ : "" });
59
139
  }
60
- case "CLOSE": {
61
- return __assign(__assign({}, state), { isExpanded: false, highlightedOptionIndex: 0 });
140
+ case "SET_HIGHLIGHTED_OPTION": {
141
+ var index = action.payload.index;
142
+ return __assign(__assign({}, state), { highlightedOptionIndex: index });
62
143
  }
63
144
  case "INPUT_CHANGE": {
64
- var _a = action.payload, value = _a.value, isAutocomplete = _a.isAutocomplete;
65
- return __assign(__assign({}, state), { value: value, options: isAutocomplete
66
- ? filterOptions(initialOptions, value)
67
- : state.options, highlightedOptionIndex: 0, isExpanded: true });
145
+ var _c = action.payload, value = _c.value, isAutocomplete = _c.isAutocomplete, isCustomEntryAllowed = _c.isCustomEntryAllowed, isMultiSelectable = _c.isMultiSelectable;
146
+ var filteredOptions = filterOptions(initialOptions, value);
147
+ var matchingOption = getMatchingOption(state.options, value);
148
+ var showCustomMultiSelectOption = Boolean(value.trim()) &&
149
+ isCustomEntryAllowed &&
150
+ isMultiSelectable &&
151
+ !matchingOption;
152
+ var optionsList = isAutocomplete
153
+ ? filteredOptions
154
+ : convertOptionsToObjects(initialOptions);
155
+ var newOptions = showCustomMultiSelectOption
156
+ ? __spreadArray([{ isCustom: true, text: value }], optionsList, true) : optionsList;
157
+ var closestMatchingOptionIndex = getClosestMatchingOptionIndex(newOptions, filteredOptions);
158
+ var singleSelectedOption = isCustomEntryAllowed
159
+ ? { isCustom: false, text: "" }
160
+ : state.singleSelectedOption;
161
+ var highlightedOptionIndex = isAutocomplete
162
+ ? 0
163
+ : closestMatchingOptionIndex;
164
+ return __assign(__assign({}, state), { value: value, onChangeValue: !isMultiSelectable
165
+ ? value
166
+ : convertOptionsToText(state.selectedOptions), options: newOptions, singleSelectedOption: singleSelectedOption, highlightedOptionIndex: highlightedOptionIndex, isDirty: true, isExpanded: true });
68
167
  }
69
168
  case "SINGLE_SELECT": {
70
- var _b = action.payload, selectedOption = _b.option, isAutocomplete = _b.isAutocomplete;
71
- return __assign(__assign({}, state), { isExpanded: false, options: isAutocomplete
72
- ? filterOptions(initialOptions, selectedOption)
73
- : state.options, value: selectedOption });
169
+ var selectedOption = action.payload.option;
170
+ var options = state.options;
171
+ return __assign(__assign({}, state), { isExpanded: false, isDirty: true, singleSelectedOption: selectedOption, options: convertOptionsToObjects(initialOptions), highlightedOptionIndex: findOptionIndex(options, selectedOption), value: selectedOption.text, onChangeValue: selectedOption.text });
74
172
  }
75
173
  case "MULTI_SELECT": {
76
- var selectedOption = action.payload.option;
77
- var selectedOptions = state.selectedOptions, options = state.options;
78
- var newSelectedOptions = getSelectedOptions(selectedOption, selectedOptions);
79
- return __assign(__assign({}, state), { value: "", options: initialOptions, highlightedOptionIndex: findOptionIndex(options, selectedOption), selectedOptions: newSelectedOptions });
174
+ var _d = action.payload, selectedOption = _d.option, multiSelectLimit = _d.multiSelectLimit;
175
+ var selectedOptions = state.selectedOptions;
176
+ var _e = getNewMultiSelectOptions(selectedOption, selectedOptions, multiSelectLimit), newOptions = _e.newOptions, limitReached = _e.limitReached;
177
+ return __assign(__assign({}, state), { limitReached: limitReached, selectedOptions: newOptions, onChangeValue: convertOptionsToText(newOptions) });
80
178
  }
81
179
  case "MULTI_SELECT_REMOVE": {
82
- var option_1 = action.payload.option;
180
+ var _f = action.payload, option_1 = _f.option, multiSelectLimit = _f.multiSelectLimit;
83
181
  var selectedOptions = state.selectedOptions;
84
- return __assign(__assign({}, state), { selectedOptions: selectedOptions.filter(function (selectedOption) { return option_1 !== selectedOption; }) });
182
+ var newSelectedOptions = selectedOptions.filter(function (selectedOption) { return option_1.text !== selectedOption.text; });
183
+ var limitReached = multiSelectLimitReached(newSelectedOptions, multiSelectLimit);
184
+ return __assign(__assign({}, state), { limitReached: limitReached, onChangeValue: convertOptionsToText(newSelectedOptions), selectedOptions: newSelectedOptions });
85
185
  }
86
186
  case "KEYDOWN": {
87
- var _c = action.payload, key = _c.key, isAutocomplete = _c.isAutocomplete, isMultiSelectable = _c.isMultiSelectable;
187
+ var _g = action.payload, key = _g.key, isMultiSelectable = _g.isMultiSelectable, multiSelectLimit = _g.multiSelectLimit;
88
188
  var isExpanded = state.isExpanded, highlightedOptionIndex = state.highlightedOptionIndex, options = state.options, selectedOptions = state.selectedOptions;
189
+ var hasNoHighlightedOption = highlightedOptionIndex === undefined;
89
190
  if (key === "Escape" && isExpanded) {
90
- return __assign(__assign({}, state), { isExpanded: false, highlightedOptionIndex: 0 });
191
+ return __assign(__assign({}, state), { showAllTags: false, isExpanded: false, highlightedOptionIndex: 0 });
91
192
  }
92
193
  if (key === "ArrowDown" && isExpanded) {
93
- return __assign(__assign({}, state), { highlightedOptionIndex: highlightedOptionIndex === options.length - 1
94
- ? 0
95
- : highlightedOptionIndex + 1 });
194
+ return __assign(__assign({}, state), { highlightedOptionIndex: getKeydownOptionToHighlight({
195
+ isNext: true,
196
+ options: options,
197
+ highlightedOptionIndex: highlightedOptionIndex,
198
+ }) });
96
199
  }
97
200
  if (key === "ArrowUp" && isExpanded) {
98
- return __assign(__assign({}, state), { highlightedOptionIndex: highlightedOptionIndex === 0
99
- ? options.length - 1
100
- : highlightedOptionIndex - 1 });
101
- }
102
- if (key === "ArrowDown" && !isExpanded) {
103
- return __assign(__assign({}, state), { isExpanded: true, highlightedOptionIndex: isMultiSelectable && selectedOptions.length
104
- ? findOptionIndex(options, selectedOptions[selectedOptions.length - 1])
105
- : 0 });
201
+ return __assign(__assign({}, state), { highlightedOptionIndex: getKeydownOptionToHighlight({
202
+ isNext: false,
203
+ options: options,
204
+ highlightedOptionIndex: highlightedOptionIndex,
205
+ }) });
106
206
  }
107
- if (key === "ArrowUp" && !isExpanded) {
108
- return __assign(__assign({}, state), { isExpanded: true, highlightedOptionIndex: isMultiSelectable && selectedOptions.length
109
- ? findOptionIndex(options, selectedOptions[selectedOptions.length - 1])
110
- : options.length - 1 });
207
+ if (["ArrowDown", "ArrowUp"].includes(key) && !isExpanded) {
208
+ return __assign(__assign({}, state), { isExpanded: true, highlightedOptionIndex: 0 });
111
209
  }
112
210
  if (key === "Enter" && isExpanded) {
211
+ if (hasNoHighlightedOption) {
212
+ return __assign(__assign({}, state), { isExpanded: false });
213
+ }
113
214
  if (isMultiSelectable) {
114
- var newSelectedOptionIds = getSelectedOptions(options[highlightedOptionIndex], selectedOptions);
115
- return __assign(__assign({}, state), { value: "", options: initialOptions, selectedOptions: newSelectedOptionIds });
215
+ var _h = getNewMultiSelectOptions(options[highlightedOptionIndex], selectedOptions, multiSelectLimit), newOptions = _h.newOptions, limitReached = _h.limitReached;
216
+ return __assign(__assign({}, state), { limitReached: limitReached, onChangeValue: convertOptionsToText(newOptions), selectedOptions: newOptions });
116
217
  }
117
218
  else {
118
- return __assign(__assign({}, state), { isExpanded: false, options: isAutocomplete
119
- ? filterOptions(initialOptions, options[highlightedOptionIndex])
120
- : options, value: options[highlightedOptionIndex] });
219
+ var newSelectedOption = options[highlightedOptionIndex];
220
+ return __assign(__assign({}, state), { isExpanded: false, singleSelectedOption: newSelectedOption, options: convertOptionsToObjects(initialOptions), onChangeValue: newSelectedOption.text, value: newSelectedOption.text });
121
221
  }
122
222
  }
123
223
  return state;
@@ -128,27 +228,179 @@ var reducer = function (initialOptions) {
128
228
  };
129
229
  };
130
230
 
131
- /** Use `ComboBox` to provide a searchable dropdown list that allows users to select from or filter through multiple options. */
231
+ var ComboBoxTags = function (_a) {
232
+ var ref = _a.ref, selectedOptions = _a.selectedOptions, showAllTags = _a.showAllTags, isDisabled = _a.isDisabled, isError = _a.isError, isDarkSurface = _a.isDarkSurface, visibleTagCount = _a.visibleTagCount, inputSize = _a.inputSize, isReadOnly = _a.isReadOnly, onTagBlur = _a.onTagBlur, onTagClick = _a.onTagClick, onTagKeyDown = _a.onTagKeyDown, onShowAllTagsClick = _a.onShowAllTagsClick;
233
+ var id = useId();
234
+ var tagLimit = !showAllTags ? visibleTagCount : undefined;
235
+ var showHiddenTagCount = !showAllTags && selectedOptions.length > visibleTagCount;
236
+ return (React__default.createElement("div", { ref: ref, className: classNames("arc-ComboBoxTags", suffixModifier("arc-ComboBoxTags--size", inputSize), {
237
+ "arc-ComboBoxTags--disabled": isDisabled,
238
+ "arc-ComboBoxTags--readOnly": isReadOnly,
239
+ "arc-ComboBoxTags--invalid": isError,
240
+ "arc-ComboBoxTags--onDarkSurface": isDarkSurface,
241
+ }) },
242
+ selectedOptions.slice(0, tagLimit).map(function (option, i) { return (React__default.createElement("button", { type: "button", disabled: isDisabled, key: "".concat(id, "-selectedOption-").concat(i), className: "arc-ComboBoxTags-tag", "aria-label": "".concat(option.text, ", press space or enter to remove"), onBlur: onTagBlur, onMouseDown: onTagClick(option), onKeyDown: onTagKeyDown(option) },
243
+ React__default.createElement("div", { "aria-hidden": true, className: "arc-ComboBoxTags-tagInner" },
244
+ React__default.createElement("span", null, option.text),
245
+ React__default.createElement("div", { className: "arc-ComboBoxTags-tagIcon" },
246
+ React__default.createElement(ThemeIcon, { icon: "comboboxTagRemove", size: 20 }))))); }),
247
+ showHiddenTagCount && (React__default.createElement("button", { type: "button", disabled: isDisabled, onClick: onShowAllTagsClick, className: "arc-ComboBoxTags-showHiddenButton", "aria-label": "Show all selected options" },
248
+ React__default.createElement("span", { className: "arc-ComboBoxTags-showHiddenButtonContent" },
249
+ "+\u00A0",
250
+ selectedOptions.length - visibleTagCount,
251
+ "\u00A0more")))));
252
+ };
253
+
254
+ var ComboBoxListItemInner = function (_a) {
255
+ var isHighlighted = _a.isHighlighted, isSingleSelected = _a.isSingleSelected, children = _a.children;
256
+ return (React__default.createElement("div", { className: classNames("arc-ComboBoxListItemInner", {
257
+ "arc-ComboBoxListItemInner--highlighted": isHighlighted,
258
+ "arc-ComboBoxListItemInner--singleSelected": isSingleSelected,
259
+ }) }, children));
260
+ };
261
+
262
+ var ComboBoxRegularOption = function (_a) {
263
+ var option = _a.option, isDisabled = _a.isDisabled, isMultiSelectable = _a.isMultiSelectable, isHighlighted = _a.isHighlighted, isSingleSelected = _a.isSingleSelected, isMultiSelected = _a.isMultiSelected;
264
+ return (React__default.createElement(ComboBoxListItemInner, { isHighlighted: isHighlighted, isSingleSelected: isSingleSelected },
265
+ React__default.createElement("div", { className: "arc-ComboBoxRegularOption-container" },
266
+ isMultiSelectable && (React__default.createElement("div", { className: classNames("arc-ComboBoxRegularOption-icon", "arc-ComboBoxRegularOption-icon--checkbox", {
267
+ "arc-ComboBoxRegularOption-icon--checkboxSelected": isMultiSelected,
268
+ "arc-ComboBoxRegularOption-icon--checkboxDisabled": isDisabled,
269
+ }) },
270
+ React__default.createElement(ThemeIcon, { size: 24, icon: "comboboxSelected" }))),
271
+ React__default.createElement("div", { className: "arc-ComboBoxRegularOption-text" },
272
+ React__default.createElement(Text, null, option.text)),
273
+ !isMultiSelectable && isSingleSelected && (React__default.createElement("div", { className: "arc-ComboBoxRegularOption-icon" },
274
+ React__default.createElement(ThemeIcon, { size: 24, icon: "comboboxSelected" }))))));
275
+ };
276
+
277
+ var ComboBoxCustomOption = function (_a) {
278
+ var option = _a.option, selectedOptions = _a.selectedOptions, customOptionSupportingCopy = _a.customOptionSupportingCopy, optionsLength = _a.optionsLength, isHighlighted = _a.isHighlighted, isSelected = _a.isSelected;
279
+ var prefixText = getMatchingOption(selectedOptions, option.text)
280
+ ? "Remove"
281
+ : "Add";
282
+ return (React__default.createElement(React__default.Fragment, null,
283
+ React__default.createElement(ComboBoxListItemInner, { isHighlighted: isHighlighted, isSingleSelected: isSelected },
284
+ React__default.createElement(Text, null,
285
+ prefixText,
286
+ ": \"",
287
+ option.text,
288
+ "\""),
289
+ customOptionSupportingCopy && (React__default.createElement("div", null,
290
+ React__default.createElement(VerticalSpace, { size: "4" }),
291
+ React__default.createElement(Text, { size: "xs" }, customOptionSupportingCopy)))),
292
+ optionsLength > 1 && (React__default.createElement(React__default.Fragment, null,
293
+ React__default.createElement("div", { className: "arc-ComboBoxCustomOption-rule" },
294
+ React__default.createElement("div", { className: "arc-ComboBoxCustomOption-ruleWrapper" },
295
+ React__default.createElement(Rule, null))),
296
+ React__default.createElement(VerticalSpace, { size: "8" })))));
297
+ };
298
+
299
+ var ComboBoxNoResults = function (_a) {
300
+ var noResultsSupportingCopy = _a.noResultsSupportingCopy, value = _a.value;
301
+ return (React__default.createElement("li", { "aria-disabled": true, "aria-selected": false, role: "option", className: "arc-ComboBoxNoResults" },
302
+ React__default.createElement(ComboBoxListItemInner, null,
303
+ React__default.createElement("div", { className: "arc-ComboBoxNoResults-container" },
304
+ React__default.createElement("div", { className: "arc-ComboBoxNoResults-icon" },
305
+ React__default.createElement(ThemeIcon, { size: 24, icon: "comboboxNoResults" })),
306
+ React__default.createElement("div", { className: "arc-ComboBoxNoResults-text" },
307
+ React__default.createElement(Text, null,
308
+ "No results for \"",
309
+ value,
310
+ "\""),
311
+ noResultsSupportingCopy && (React__default.createElement(React__default.Fragment, null,
312
+ React__default.createElement(VerticalSpace, { size: "4" }),
313
+ React__default.createElement(Text, { size: "xs" }, noResultsSupportingCopy))))))));
314
+ };
315
+
316
+ var ComboBoxOptions = function (_a) {
317
+ var options = _a.options, listBoxId = _a.listBoxId, onMouseMove = _a.onMouseMove, onMouseDown = _a.onMouseDown, isMultiSelectable = _a.isMultiSelectable, noResultsSupportingCopy = _a.noResultsSupportingCopy, customOptionSupportingCopy = _a.customOptionSupportingCopy, selectedOptions = _a.selectedOptions, singleSelectedOption = _a.singleSelectedOption, highlightedOptionIndex = _a.highlightedOptionIndex, setOptionRef = _a.setOptionRef, limitReached = _a.limitReached, value = _a.value;
318
+ var isHighlighted = function (index, currentHighlightIndex) {
319
+ return index === currentHighlightIndex;
320
+ };
321
+ var isSingleSelected = function (option, selectedOption) { return option.text === selectedOption.text; };
322
+ var isMultiSelected = function (option, selectedOptions) {
323
+ return selectedOptions.some(function (selectedOption) { return option.text === selectedOption.text; });
324
+ };
325
+ var isOptionDisabled = function (option, selectedOptions) { return limitReached && !isMultiSelected(option, selectedOptions); };
326
+ return (React__default.createElement(React__default.Fragment, null, options.length ? (options.map(function (option, i) { return (React__default.createElement("li", { key: option.text, role: "option", id: "".concat(listBoxId, "-").concat(i), ref: setOptionRef(i), onMouseMove: onMouseMove(i), onMouseDown: onMouseDown(option), "aria-disabled": isOptionDisabled(option, selectedOptions), "aria-selected": isMultiSelectable
327
+ ? isMultiSelected(option, selectedOptions)
328
+ : isSingleSelected(option, singleSelectedOption), className: classNames("arc-ComboBoxOptions-listItem", {
329
+ "arc-ComboBoxOptions-listItem--disabled": isOptionDisabled(option, selectedOptions),
330
+ }) }, option.isCustom ? (React__default.createElement(ComboBoxCustomOption, { option: option, optionsLength: options.length, customOptionSupportingCopy: customOptionSupportingCopy, selectedOptions: selectedOptions, isHighlighted: isHighlighted(i, highlightedOptionIndex), isSelected: isSingleSelected(option, singleSelectedOption) })) : (React__default.createElement(ComboBoxRegularOption, { option: option, isDisabled: isOptionDisabled(option, selectedOptions), isMultiSelectable: isMultiSelectable, isHighlighted: isHighlighted(i, highlightedOptionIndex), isMultiSelected: isMultiSelected(option, selectedOptions), isSingleSelected: isSingleSelected(option, singleSelectedOption) })))); })) : (React__default.createElement(ComboBoxNoResults, { noResultsSupportingCopy: noResultsSupportingCopy, value: value }))));
331
+ };
332
+
333
+ var KeyNames;
334
+ (function (KeyNames) {
335
+ KeyNames["ArrowUp"] = "ArrowUp";
336
+ KeyNames["ArrowDown"] = "ArrowDown";
337
+ KeyNames["Home"] = "Home";
338
+ KeyNames["Enter"] = "Enter";
339
+ KeyNames["Escape"] = "Escape";
340
+ KeyNames["Space"] = " ";
341
+ })(KeyNames || (KeyNames = {}));
342
+
343
+ var isSelectionKey = function (key) {
344
+ return key === KeyNames.Space || key === KeyNames.Enter;
345
+ };
346
+
347
+ var ComboBoxClearButton = function (_a) {
348
+ var ref = _a.ref, inputSize = _a.inputSize, tooltip = _a.tooltip, onKeyDown = _a.onKeyDown, onMouseDown = _a.onMouseDown, onBlur = _a.onBlur, isDarkSurface = _a.isDarkSurface, props = __rest(_a, ["ref", "inputSize", "tooltip", "onKeyDown", "onMouseDown", "onBlur", "isDarkSurface"]);
349
+ return (React__default.createElement("button", __assign({}, props, { type: "button", ref: ref, "aria-label": tooltip, onMouseDown: onMouseDown, onKeyDown: onKeyDown, onBlur: onBlur, className: classNames("arc-ComboBoxClearButton", suffixModifier("arc-ComboBoxClearButton--size", inputSize), {
350
+ "arc-ComboBoxClearButton--onDarkSurface": isDarkSurface,
351
+ }) }),
352
+ React__default.createElement("div", { className: "arc-ComboBoxClearButton-icon" },
353
+ React__default.createElement(ThemeIcon, { "aria-hidden": true, icon: "comboboxClear" }))));
354
+ };
355
+
356
+ /** Use `ComboBox` to assist a text input with a dropdown list of options. */
132
357
  var ComboBox = function (_a) {
133
- var ref = _a.ref, name = _a.name, onBlur = _a.onBlur, onFocus = _a.onFocus, label = _a.label, helper = _a.helper, id = _a.id, initialOptions = _a.options, hideLabel = _a.hideLabel, isFluid = _a.isFluid, errorMessage = _a.errorMessage, disclosureTitle = _a.disclosureTitle, disclosureText = _a.disclosureText, onClickDisclosure = _a.onClickDisclosure, listBoxAriaLabel = _a.listBoxAriaLabel, _b = _a.defaultValue, defaultValue = _b === void 0 ? "" : _b, _c = _a.labelSize, labelSize = _c === void 0 ? "l" : _c, _d = _a.isMultiSelectable, isMultiSelectable = _d === void 0 ? false : _d, _e = _a.isDisabled, isDisabled = _e === void 0 ? false : _e, _f = _a.isRequired, isRequired = _f === void 0 ? false : _f, _g = _a.isAutocomplete, isAutocomplete = _g === void 0 ? false : _g, props = __rest(_a, ["ref", "name", "onBlur", "onFocus", "label", "helper", "id", "options", "hideLabel", "isFluid", "errorMessage", "disclosureTitle", "disclosureText", "onClickDisclosure", "listBoxAriaLabel", "defaultValue", "labelSize", "isMultiSelectable", "isDisabled", "isRequired", "isAutocomplete"]);
358
+ var ref = _a.ref, name = _a.name, onBlur = _a.onBlur, onFocus = _a.onFocus, label = _a.label, helper = _a.helper, id = _a.id, hideLabel = _a.hideLabel, isFluid = _a.isFluid, errorMessage = _a.errorMessage, disclosureTitle = _a.disclosureTitle, disclosureText = _a.disclosureText, onClickDisclosure = _a.onClickDisclosure, listBoxAriaLabel = _a.listBoxAriaLabel, prefixIcon = _a.prefixIcon, onChange = _a.onChange, noResultsSupportingCopy = _a.noResultsSupportingCopy, customOptionSupportingCopy = _a.customOptionSupportingCopy, multiSelectLimit = _a.multiSelectLimit, initialOptions = _a.options, _b = _a.clearButtonTooltip, clearButtonTooltip = _b === void 0 ? "Clear input" : _b, _c = _a.defaultSelectedValues, defaultSelectedValues = _c === void 0 ? [] : _c, _d = _a.defaultValue, defaultValue = _d === void 0 ? "" : _d, _e = _a.size, size = _e === void 0 ? "m" : _e, _f = _a.visibleTagCount, visibleTagCount = _f === void 0 ? 5 : _f, _g = _a.isClearButtonEnabled, isClearButtonEnabled = _g === void 0 ? false : _g, _h = _a.isReadOnly, isReadOnly = _h === void 0 ? false : _h, _j = _a.isMultiSelectable, isMultiSelectable = _j === void 0 ? false : _j, _k = _a.isDisabled, isDisabled = _k === void 0 ? false : _k, _l = _a.isRequired, isRequired = _l === void 0 ? false : _l, _m = _a.isAutocomplete, isAutocomplete = _m === void 0 ? false : _m, _o = _a.isCustomEntryAllowed, isCustomEntryAllowed = _o === void 0 ? false : _o, props = __rest(_a, ["ref", "name", "onBlur", "onFocus", "label", "helper", "id", "hideLabel", "isFluid", "errorMessage", "disclosureTitle", "disclosureText", "onClickDisclosure", "listBoxAriaLabel", "prefixIcon", "onChange", "noResultsSupportingCopy", "customOptionSupportingCopy", "multiSelectLimit", "options", "clearButtonTooltip", "defaultSelectedValues", "defaultValue", "size", "visibleTagCount", "isClearButtonEnabled", "isReadOnly", "isMultiSelectable", "isDisabled", "isRequired", "isAutocomplete", "isCustomEntryAllowed"]);
134
359
  var listBoxId = useId();
360
+ var surface = useContext(Context).surface;
361
+ var _p = useThemeElement(), themeElement = _p[0], setThemeElement = _p[1];
135
362
  var listItemRefs = useRef([]);
136
- var containerRef = useRef(null);
363
+ var comboBoxContainerRef = useRef(null);
364
+ var tagContainerRef = useRef(null);
137
365
  var inputRef = useRef(null);
138
- var _h = useThemeElement(), themeElement = _h[0], setThemeElement = _h[1];
139
- var _j = useReducer(reducer(initialOptions), {
366
+ var prevOnChangeValueRef = useRef(null);
367
+ var _q = useReducer(reducer(initialOptions), {
140
368
  isExpanded: false,
369
+ showAllTags: false,
370
+ isDirty: Boolean(defaultValue),
371
+ singleSelectedOption: { isCustom: false, text: defaultValue },
372
+ limitReached: defaultSelectedValues && multiSelectLimit
373
+ ? defaultSelectedValues.length > multiSelectLimit
374
+ : false,
141
375
  value: defaultValue,
142
- options: initialOptions,
143
- highlightedOptionIndex: 0,
144
- selectedOptions: [],
145
- }), _k = _j[0], isExpanded = _k.isExpanded, value = _k.value, options = _k.options, highlightedOptionIndex = _k.highlightedOptionIndex, selectedOptions = _k.selectedOptions, dispatch = _j[1];
376
+ onChangeValue: isMultiSelectable
377
+ ? defaultSelectedValues || null
378
+ : defaultValue || null,
379
+ options: convertOptionsToObjects(initialOptions),
380
+ selectedOptions: isMultiSelectable
381
+ ? convertOptionsToObjects(defaultSelectedValues).slice(0, multiSelectLimit)
382
+ : [],
383
+ }), _r = _q[0], isExpanded = _r.isExpanded, value = _r.value, options = _r.options, showAllTags = _r.showAllTags, singleSelectedOption = _r.singleSelectedOption, highlightedOptionIndex = _r.highlightedOptionIndex, selectedOptions = _r.selectedOptions, limitReached = _r.limitReached, isDirty = _r.isDirty, onChangeValue = _r.onChangeValue, dispatch = _q[1];
146
384
  var ariaDescribedby = useAriaDescribedby({
147
385
  errorMessage: errorMessage,
148
386
  id: id,
149
387
  helper: helper,
150
388
  disclosureText: disclosureText,
151
389
  }).ariaDescribedby;
390
+ useEffect(function () {
391
+ var hasValueChanged = JSON.stringify(onChangeValue) !==
392
+ JSON.stringify(prevOnChangeValueRef.current);
393
+ if (hasValueChanged && onChange && onChangeValue) {
394
+ prevOnChangeValueRef.current = onChangeValue;
395
+ onChange(onChangeValue);
396
+ }
397
+ }, [onChangeValue, onChange]);
398
+ var hasHighlightedOption = typeof highlightedOptionIndex !== "undefined";
399
+ var listVerticalPadding = "12";
400
+ var isDarkSurface = surface === "dark";
401
+ var canOpenMenu = !isExpanded && !isReadOnly;
402
+ var showClearButton = isClearButtonEnabled && isDirty && value && !isDisabled && !isReadOnly;
403
+ var stackAutoCompleteIconFirst = selectedOptions.length && isAutocomplete && !showClearButton;
152
404
  var getTextInputRef = function (elementRef) {
153
405
  inputRef.current = elementRef;
154
406
  if (ref && typeof ref === "object") {
@@ -158,18 +410,24 @@ var ComboBox = function (_a) {
158
410
  ref(elementRef);
159
411
  }
160
412
  };
413
+ var setOptionRef = function (index) { return function (el) {
414
+ return (listItemRefs.current[index] = el);
415
+ }; };
161
416
  var setScrollPosition = function (listEl) {
162
- var listItemEl = listItemRefs.current[highlightedOptionIndex];
163
- if (listItemEl && listEl) {
164
- var selectedOptionIsBelowOverFlow = listItemEl.offsetTop + listItemEl.offsetHeight >
165
- listEl.offsetHeight + listEl.scrollTop;
166
- var selectedOptionIsAboveOverFlow = listItemEl.offsetTop < listEl.scrollTop;
167
- if (selectedOptionIsBelowOverFlow) {
168
- listEl.scrollTop =
169
- listItemEl.offsetTop + listItemEl.offsetHeight - listEl.offsetHeight;
170
- }
171
- if (selectedOptionIsAboveOverFlow) {
172
- listEl.scrollTop = listItemEl.offsetTop;
417
+ if (hasHighlightedOption) {
418
+ var listItemEl = listItemRefs.current[highlightedOptionIndex];
419
+ if (listItemEl && listEl) {
420
+ var listItemOffset = listItemEl.offsetTop - parseInt(listVerticalPadding);
421
+ var selectedOptionIsBelowOverFlow = listItemOffset + listItemEl.offsetHeight >
422
+ listEl.offsetHeight + listEl.scrollTop;
423
+ var selectedOptionIsAboveOverFlow = listItemOffset < listEl.scrollTop;
424
+ if (selectedOptionIsBelowOverFlow) {
425
+ listEl.scrollTop =
426
+ listItemOffset + listItemEl.offsetHeight - listEl.offsetHeight;
427
+ }
428
+ if (selectedOptionIsAboveOverFlow) {
429
+ listEl.scrollTop = listItemOffset;
430
+ }
173
431
  }
174
432
  }
175
433
  };
@@ -181,6 +439,7 @@ var ComboBox = function (_a) {
181
439
  dispatch({
182
440
  type: "MULTI_SELECT",
183
441
  payload: {
442
+ multiSelectLimit: multiSelectLimit,
184
443
  option: itemOption,
185
444
  },
186
445
  });
@@ -189,7 +448,6 @@ var ComboBox = function (_a) {
189
448
  dispatch({
190
449
  type: "SINGLE_SELECT",
191
450
  payload: {
192
- isAutocomplete: isAutocomplete,
193
451
  option: itemOption,
194
452
  },
195
453
  });
@@ -201,94 +459,230 @@ var ComboBox = function (_a) {
201
459
  dispatch({
202
460
  type: "INPUT_CHANGE",
203
461
  payload: {
462
+ isCustomEntryAllowed: isCustomEntryAllowed,
463
+ isMultiSelectable: isMultiSelectable,
204
464
  isAutocomplete: isAutocomplete,
205
465
  value: e.target.value,
206
466
  },
207
467
  });
208
468
  };
209
- var onInputClick = function () {
210
- isAutocomplete &&
469
+ var onMouseDown = function (preventDefault) { return function (e) {
470
+ var _a;
471
+ preventDefault && e.preventDefault();
472
+ if (isDisabled) {
473
+ return;
474
+ }
475
+ if (canOpenMenu) {
476
+ dispatch({
477
+ type: "OPEN",
478
+ });
479
+ }
480
+ if (isExpanded) {
481
+ dispatch({
482
+ type: "CLOSE_MENU",
483
+ });
484
+ }
485
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
486
+ }; };
487
+ var onInteractOutsideDropdown = function (e) {
488
+ if (comboBoxContainerRef.current &&
489
+ !comboBoxContainerRef.current.contains(e.currentTarget)) {
490
+ dispatch({
491
+ type: "EXIT_INPUT",
492
+ payload: {
493
+ isMultiSelectable: isMultiSelectable,
494
+ isCustomEntryAllowed: isCustomEntryAllowed,
495
+ },
496
+ });
497
+ }
498
+ };
499
+ var onInputFocus = function (e) {
500
+ if (canOpenMenu) {
211
501
  dispatch({
212
502
  type: "OPEN",
503
+ });
504
+ }
505
+ onFocus && onFocus(e);
506
+ };
507
+ var onInputBlur = function (e) {
508
+ var _a;
509
+ if (!isExpanded &&
510
+ !((_a = comboBoxContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
511
+ dispatch({
512
+ type: "EXIT_INPUT",
213
513
  payload: {
214
514
  isMultiSelectable: isMultiSelectable,
515
+ isCustomEntryAllowed: isCustomEntryAllowed,
215
516
  },
216
517
  });
518
+ }
519
+ onBlur && onBlur(e);
217
520
  };
218
- var onInteractOutside = function (e) {
219
- if (containerRef.current &&
220
- !containerRef.current.contains(e.currentTarget)) {
521
+ var onClearButtonBlur = function (e) {
522
+ var _a;
523
+ if (!isExpanded &&
524
+ !((_a = comboBoxContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
221
525
  dispatch({
222
- type: "CLOSE",
526
+ type: "EXIT_INPUT",
527
+ payload: {
528
+ isMultiSelectable: isMultiSelectable,
529
+ isCustomEntryAllowed: isCustomEntryAllowed,
530
+ },
223
531
  });
224
532
  }
225
533
  };
226
534
  var onInputKeyDown = function (e) {
535
+ if (!isReadOnly) {
536
+ if (isSelectionKey(e.key)) {
537
+ e.preventDefault();
538
+ }
539
+ dispatch({
540
+ type: "KEYDOWN",
541
+ payload: {
542
+ key: e.key,
543
+ isCustomEntryAllowed: isCustomEntryAllowed,
544
+ isMultiSelectable: isMultiSelectable,
545
+ multiSelectLimit: multiSelectLimit,
546
+ },
547
+ });
548
+ }
549
+ };
550
+ var setHighlightedOption = function (index) { return function () {
227
551
  dispatch({
228
- type: "KEYDOWN",
552
+ type: "SET_HIGHLIGHTED_OPTION",
229
553
  payload: {
230
- key: e.key,
231
- isAutocomplete: isAutocomplete,
232
- isMultiSelectable: isMultiSelectable,
554
+ index: index,
233
555
  },
234
556
  });
235
- };
236
- var onMultiSelectRemove = function (option) { return function (e) {
557
+ }; };
558
+ var onMultiSelectRemove = function (option) {
237
559
  var _a;
238
- e.preventDefault();
239
- e.stopPropagation();
240
560
  dispatch({
241
561
  type: "MULTI_SELECT_REMOVE",
242
562
  payload: {
243
563
  option: option,
564
+ multiSelectLimit: multiSelectLimit,
244
565
  },
245
566
  });
246
567
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
568
+ };
569
+ var onTagClick = function (option) { return function (e) {
570
+ e.preventDefault();
571
+ e.stopPropagation();
572
+ !isReadOnly && onMultiSelectRemove(option);
573
+ }; };
574
+ var onTagKeyDown = function (option) { return function (e) {
575
+ if (isSelectionKey(e.key)) {
576
+ e.preventDefault();
577
+ e.stopPropagation();
578
+ !isReadOnly && onMultiSelectRemove(option);
579
+ }
247
580
  }; };
581
+ var onShowAllTagsClick = function () {
582
+ var _a, _b;
583
+ dispatch({
584
+ type: "SHOW_ALL_TAGS",
585
+ });
586
+ if (!isReadOnly) {
587
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
588
+ }
589
+ else {
590
+ ((_b = tagContainerRef.current) === null || _b === void 0 ? void 0 : _b.firstChild).focus();
591
+ }
592
+ };
593
+ var onTagBlur = function (e) {
594
+ var _a;
595
+ if (isReadOnly &&
596
+ !((_a = comboBoxContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
597
+ dispatch({
598
+ type: "EXIT_INPUT",
599
+ payload: {
600
+ isMultiSelectable: isMultiSelectable,
601
+ isCustomEntryAllowed: isCustomEntryAllowed,
602
+ },
603
+ });
604
+ }
605
+ };
606
+ var onClearButtonMouseDown = function (e) {
607
+ var _a, _b;
608
+ e.preventDefault();
609
+ dispatch({
610
+ type: "CLEAR",
611
+ payload: {
612
+ isCustomEntryAllowed: isCustomEntryAllowed,
613
+ isMultiSelectable: isMultiSelectable,
614
+ },
615
+ });
616
+ if (!((_a = comboBoxContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))) {
617
+ (_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.focus();
618
+ }
619
+ };
620
+ var onClearButtonKeydown = function (e) {
621
+ var _a;
622
+ if (isSelectionKey(e.key)) {
623
+ e.preventDefault();
624
+ dispatch({
625
+ type: "CLEAR",
626
+ payload: {
627
+ isCustomEntryAllowed: isCustomEntryAllowed,
628
+ isMultiSelectable: isMultiSelectable,
629
+ },
630
+ });
631
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
632
+ }
633
+ };
248
634
  var onOpenAutoFocus = function (e) {
249
635
  var _a;
250
636
  e.preventDefault();
251
637
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
252
638
  };
253
- return (React__default.createElement("div", { ref: setThemeElement, className: classNames("arc-ComboBox", {
639
+ return (React__default.createElement("div", __assign({ ref: setThemeElement, className: classNames("arc-ComboBox", suffixModifier("arc-ComboBox--size", size), {
254
640
  "arc-ComboBox--constrained": !isFluid,
255
- }) },
256
- React__default.createElement("div", { ref: containerRef },
641
+ "arc-ComboBox--invalid": errorMessage,
642
+ "arc-ComboBox--disabled": isDisabled,
643
+ "arc-ComboBox--expanded": isExpanded,
644
+ "arc-ComboBox--autoComplete": isAutocomplete,
645
+ "arc-ComboBox--onDarkSurface": isDarkSurface,
646
+ "arc-ComboBox--readOnly": isReadOnly,
647
+ }) }, filterAttrs(props)),
648
+ React__default.createElement("div", { ref: comboBoxContainerRef },
257
649
  React__default.createElement(Root2, { open: isExpanded },
258
- React__default.createElement(FormControl, { errorMessage: errorMessage, helper: helper, htmlFor: id, isDisabled: isDisabled, label: label, hideLabel: hideLabel, labelSize: labelSize, requirementStatus: isRequired ? "required" : "optional", disclosureTitle: disclosureTitle, disclosureText: disclosureText, onClickDisclosure: onClickDisclosure },
259
- React__default.createElement("div", { onClick: onInputClick, className: classNames("arc-ComboBox-container", {
260
- "arc-ComboBox-container--cursor": isAutocomplete,
261
- }) },
262
- React__default.createElement("div", { className: classNames("arc-ComboBox-inputWrapper", {
263
- "arc-ComboBox-inputWrapper--multiSelect": isMultiSelectable,
264
- }) },
265
- selectedOptions.length > 0 &&
266
- selectedOptions.map(function (option, i) { return (React__default.createElement("div", { className: "arc-ComboBox-tag", key: "".concat(listBoxId, "-selectedOption-").concat(i) },
267
- React__default.createElement("span", null, option),
268
- React__default.createElement("button", { className: "arc-ComboBox-tagButton", "aria-label": "".concat(option, ", press space or enter to remove"), onClick: onMultiSelectRemove(option) },
269
- React__default.createElement(ThemeIcon, { icon: "tagRemove", color: "brand", size: 20 })))); }),
270
- React__default.createElement("input", __assign({ className: "arc-ComboBox-input", ref: getTextInputRef, "aria-describedby": ariaDescribedby, "aria-invalid": errorMessage ? "true" : "false", type: "text", role: "combobox", autoComplete: "off", "aria-autocomplete": "list", "aria-controls": listBoxId, "aria-expanded": isExpanded, "aria-activedescendant": highlightedOptionIndex
271
- ? "".concat(listBoxId, "-").concat(highlightedOptionIndex)
272
- : undefined, id: id, name: name, onFocus: onFocus, onBlur: onBlur, onChange: onInputChange, onKeyDown: onInputKeyDown, disabled: isDisabled, required: isRequired, value: value }, filterAttrs(props)))),
273
- isAutocomplete && (React__default.createElement("div", { className: classNames("arc-ComboBox-inputIcon", {
274
- "arc-ComboBox-inputIcon--expanded": isExpanded,
275
- }) },
276
- React__default.createElement(Icon, { icon: BtIconChevronDown2Px, size: 24 }))))),
277
- React__default.createElement(Anchor2, null),
278
- React__default.createElement(Portal, { container: themeElement },
279
- React__default.createElement(Content2, { align: "start", sideOffset: 5, onInteractOutside: onInteractOutside, onOpenAutoFocus: onOpenAutoFocus },
280
- React__default.createElement("div", { className: "arc-ComboBox-listboxContainer" },
281
- React__default.createElement(Box, { elevationLevel: "1" },
282
- React__default.createElement("ul", { ref: setScrollPosition, id: listBoxId, className: "arc-ComboBox-list", role: "listbox", "aria-label": listBoxAriaLabel, "aria-multiselectable": isMultiSelectable }, options.length ? (options.map(function (option, i) { return (React__default.createElement("li", { id: "".concat(listBoxId, "-").concat(i), ref: function (el) {
283
- listItemRefs.current[i] = el;
284
- }, key: option, className: classNames("arc-ComboBox-listItem", {
285
- "arc-ComboBox-listItem--highlighted": i === highlightedOptionIndex,
286
- }), onMouseDown: onItemClick(option), role: "option", "aria-selected": isSelected(option, selectedOptions) },
287
- React__default.createElement("div", { className: "arc-ComboBox-listItemText" }, option),
288
- React__default.createElement("div", { className: classNames("arc-ComboBox-listItemIcon", {
289
- "arc-ComboBox-listItemIcon--visible": isSelected(option, selectedOptions),
650
+ React__default.createElement(FormControl, { errorMessage: errorMessage, helper: helper, htmlFor: id, isDisabled: isDisabled, label: label, hideLabel: hideLabel, labelSize: size, requirementStatus: isRequired ? "required" : "optional", disclosureTitle: disclosureTitle, disclosureText: disclosureText, onClickDisclosure: onClickDisclosure },
651
+ React__default.createElement(Anchor2, null,
652
+ React__default.createElement("div", { className: "arc-ComboBox-container" },
653
+ React__default.createElement("div", { className: classNames("arc-ComboBox-inputContainer", {
654
+ "arc-ComboBox-inputContainer--selectedOptionMode": selectedOptions.length,
655
+ }) },
656
+ React__default.createElement("div", { className: "arc-ComboBox-controls" },
657
+ selectedOptions.length > 0 && (React__default.createElement(ComboBoxTags, { ref: tagContainerRef, isReadOnly: isReadOnly, inputSize: size, isDisabled: isDisabled, isDarkSurface: isDarkSurface, isError: Boolean(errorMessage), showAllTags: showAllTags, visibleTagCount: visibleTagCount, selectedOptions: selectedOptions, onShowAllTagsClick: onShowAllTagsClick, onTagBlur: onTagBlur, onTagClick: onTagClick, onTagKeyDown: onTagKeyDown })),
658
+ React__default.createElement("div", { className: "arc-ComboBox-inputWrapper" },
659
+ prefixIcon && (React__default.createElement("div", { onMouseDown: onMouseDown(true), className: "arc-ComboBox-prefixIcon" },
660
+ React__default.createElement(Icon, { icon: prefixIcon }))),
661
+ React__default.createElement("input", { readOnly: isReadOnly, className: "arc-ComboBox-input", type: "text", role: "combobox", autoComplete: "off", ref: getTextInputRef, id: id, name: name, onMouseDown: onMouseDown(false), onFocus: onInputFocus, onBlur: onInputBlur, onChange: onInputChange, onKeyDown: onInputKeyDown, disabled: isDisabled, required: isRequired, value: value, "aria-describedby": ariaDescribedby, "aria-invalid": errorMessage ? "true" : "false", "aria-autocomplete": isAutocomplete ? "list" : "none", "aria-controls": listBoxId, "aria-expanded": isExpanded, "aria-activedescendant": hasHighlightedOption
662
+ ? "".concat(listBoxId, "-").concat(highlightedOptionIndex)
663
+ : undefined }))),
664
+ React__default.createElement("div", { className: classNames("arc-ComboBox-icons", {
665
+ "arc-ComboBox-icons--stack": selectedOptions.length,
666
+ "arc-ComboBox-icons--unreversed": stackAutoCompleteIconFirst,
667
+ }) },
668
+ showClearButton && (React__default.createElement("div", { className: "arc-ComboBox-iconContainer" },
669
+ React__default.createElement(Tooltip, { asChild: true, zIndex: 102, title: clearButtonTooltip, alignContent: "center", delayDuration: 500, side: "bottom" },
670
+ React__default.createElement(ComboBoxClearButton, { onBlur: onClearButtonBlur, isDarkSurface: isDarkSurface, inputSize: size, tooltip: clearButtonTooltip, onMouseDown: onClearButtonMouseDown, onKeyDown: onClearButtonKeydown })))),
671
+ isAutocomplete && (React__default.createElement("div", { onMouseDown: onMouseDown(true), className: classNames("arc-ComboBox-iconContainer", "arc-ComboBox-iconContainer--autoComplete", {
672
+ "arc-ComboBox-iconContainer--rotate": isExpanded,
290
673
  }) },
291
- React__default.createElement(ThemeIcon, { size: 20, icon: "selectIndicator" })))); })) : (React__default.createElement("li", { className: "arc-ComboBox-listItem", role: "option", "aria-selected": false, "aria-disabled": true }, "No matches found")))))))))));
674
+ React__default.createElement("div", { className: "arc-ComboBox-autoCompleteIcon" },
675
+ React__default.createElement(ThemeIcon, { icon: "comboboxAutoComplete" }))))))))),
676
+ React__default.createElement(Portal, { container: themeElement },
677
+ React__default.createElement(Content2, { align: "start", className: "arc-ComboBox-popoverContent", sideOffset: parseInt(listVerticalPadding), onInteractOutside: onInteractOutsideDropdown, onOpenAutoFocus: onOpenAutoFocus },
678
+ React__default.createElement("div", { onMouseLeave: setHighlightedOption(undefined), className: "arc-ComboBox-listboxContainer" },
679
+ React__default.createElement("div", { className: classNames("arc-ComboBox-listBoxInner", {
680
+ "arc-ComboBox-listBoxInner--onDarkSurface": isDarkSurface,
681
+ }) },
682
+ React__default.createElement(VerticalSpace, { size: listVerticalPadding }),
683
+ React__default.createElement("ul", { tabIndex: -1, className: "arc-ComboBox-list", role: "listbox", ref: setScrollPosition, id: listBoxId, "aria-label": listBoxAriaLabel, "aria-multiselectable": isMultiSelectable },
684
+ React__default.createElement(ComboBoxOptions, { value: value, limitReached: limitReached, customOptionSupportingCopy: customOptionSupportingCopy, noResultsSupportingCopy: noResultsSupportingCopy, setOptionRef: setOptionRef, options: options, listBoxId: listBoxId, isMultiSelectable: isMultiSelectable, selectedOptions: selectedOptions, singleSelectedOption: singleSelectedOption, highlightedOptionIndex: highlightedOptionIndex, onMouseMove: setHighlightedOption, onMouseDown: onItemClick })),
685
+ React__default.createElement(VerticalSpace, { size: listVerticalPadding })))))))));
292
686
  };
293
687
 
294
688
  export { ComboBox };