@elliemae/ds-controlled-form 2.4.1 → 2.4.2-rc.11

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 (231) hide show
  1. package/cjs/autocomplete/config/useAutocomplete.js +1 -3
  2. package/cjs/autocomplete/parts/A11yFocusedOption.js +43 -0
  3. package/cjs/autocomplete/parts/container/Container.js +36 -24
  4. package/cjs/autocomplete/parts/container/styled.js +2 -2
  5. package/cjs/autocomplete/parts/menu-list/MenuList.js +4 -2
  6. package/cjs/autocomplete/parts/styled.js +2 -0
  7. package/cjs/autocomplete/utils/listHelper.js +1 -1
  8. package/cjs/checkbox/ControlledCheckbox.js +49 -33
  9. package/cjs/checkbox/exported-related/data-test-ids.js +10 -0
  10. package/cjs/checkbox/exported-related/index.js +12 -0
  11. package/cjs/checkbox/exported-related/theming.js +13 -0
  12. package/cjs/checkbox/react-desc-prop-types.js +2 -2
  13. package/cjs/checkbox/styles.js +28 -15
  14. package/cjs/combobox/ComboBoxCTX.js +7 -4
  15. package/cjs/combobox/ComboboxDataTestids.js +1 -1
  16. package/cjs/combobox/config/useComboBox.js +21 -8
  17. package/cjs/combobox/index.js +5 -0
  18. package/cjs/combobox/parts/A11yFocusedOption.js +14 -6
  19. package/cjs/combobox/parts/A11ySelectedValues.js +0 -2
  20. package/cjs/combobox/parts/DropdownIndicator.js +4 -4
  21. package/cjs/combobox/parts/container/Container.js +14 -17
  22. package/cjs/combobox/parts/container/styled.js +13 -7
  23. package/cjs/combobox/parts/controls/Controls.js +22 -14
  24. package/cjs/combobox/parts/controls/styled.js +22 -13
  25. package/cjs/combobox/parts/controls/useOnPillsNavigation.js +3 -3
  26. package/cjs/combobox/parts/controls-input/ControlsInput.js +3 -3
  27. package/cjs/combobox/parts/controls-input/styled.js +7 -3
  28. package/cjs/combobox/parts/controls-input/useControlsInput.js +5 -5
  29. package/cjs/combobox/parts/controls-input/useKeyboardNavigation.js +37 -29
  30. package/cjs/combobox/parts/controls-input/useMaskedOnChange.js +6 -6
  31. package/cjs/combobox/parts/dropdown-indicator/DropdownIndicator.js +2 -2
  32. package/cjs/combobox/parts/header-list/HeaderList.js +4 -3
  33. package/cjs/combobox/parts/header-list/useHeaderListHandlers.js +11 -7
  34. package/cjs/combobox/parts/menu-list/MenuList.js +10 -5
  35. package/cjs/combobox/parts/menu-list/styled.js +16 -9
  36. package/cjs/combobox/parts/menu-list/useItemRenderer.js +17 -15
  37. package/cjs/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +1 -1
  38. package/cjs/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +2 -0
  39. package/cjs/combobox/parts/multi-selected-values-container/useGroupPills.js +13 -10
  40. package/cjs/combobox/react-desc-prop-types.js +3 -2
  41. package/cjs/combobox/theming.js +13 -0
  42. package/cjs/combobox/utils/listHelper.js +12 -1
  43. package/cjs/date-time-picker/config/useChangeHandlers.js +8 -12
  44. package/cjs/date-time-picker/config/useControlledDateTimePicker.js +13 -9
  45. package/cjs/date-time-picker/config/useFocusTracker.js +136 -0
  46. package/cjs/date-time-picker/config/useGetReferences.js +40 -19
  47. package/cjs/date-time-picker/config/useGlobalKeyHandlers.js +8 -12
  48. package/cjs/date-time-picker/parts/ClearButton/ClearButton.js +12 -2
  49. package/cjs/date-time-picker/parts/ClearButton/useClearButton.js +12 -25
  50. package/cjs/date-time-picker/parts/ControlledDateTimePickerContent.js +4 -7
  51. package/cjs/date-time-picker/parts/DateInputs/DDInput.js +8 -2
  52. package/cjs/date-time-picker/parts/DateInputs/DateInputs.js +9 -4
  53. package/cjs/date-time-picker/parts/DateInputs/MMInput.js +8 -2
  54. package/cjs/date-time-picker/parts/DateInputs/YYYYInput.js +8 -2
  55. package/cjs/date-time-picker/parts/DateInputs/useDateInputs.js +76 -95
  56. package/cjs/date-time-picker/parts/Pickers/Calendar/CalendarHead.js +31 -5
  57. package/cjs/date-time-picker/parts/Pickers/Calendar/Day.js +16 -10
  58. package/cjs/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.js +12 -12
  59. package/cjs/date-time-picker/parts/Pickers/Calendar/useFocusLogic.js +2 -38
  60. package/cjs/date-time-picker/parts/Pickers/Calendar/useKeyboardHandlers.js +40 -73
  61. package/cjs/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.js +18 -27
  62. package/cjs/date-time-picker/parts/Pickers/CalendarWithTimeWheel/CalendarWithTimeWheelIconTrigger.js +1 -0
  63. package/cjs/date-time-picker/parts/Pickers/CalendarWithTimeWheel/useConfigCalendarWithTimeWheelCTX.js +17 -23
  64. package/cjs/date-time-picker/parts/Pickers/TimeWheel/HoursList.js +13 -7
  65. package/cjs/date-time-picker/parts/Pickers/TimeWheel/MeridiemList.js +14 -8
  66. package/cjs/date-time-picker/parts/Pickers/TimeWheel/MinutesList.js +13 -7
  67. package/cjs/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.js +36 -230
  68. package/cjs/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.js +11 -13
  69. package/cjs/date-time-picker/parts/TimeInputs/HHInput.js +8 -2
  70. package/cjs/date-time-picker/parts/TimeInputs/MeridiemInput.js +8 -2
  71. package/cjs/date-time-picker/parts/TimeInputs/MinutesInput.js +8 -2
  72. package/cjs/date-time-picker/parts/TimeInputs/TimeInputs.js +11 -6
  73. package/cjs/date-time-picker/parts/TimeInputs/useTimeInputs.js +44 -74
  74. package/cjs/date-time-picker/utils/constants.js +0 -12
  75. package/cjs/date-time-picker/utils/hooks/useGetStartingFocusedDay.js +38 -36
  76. package/cjs/index.js +16 -7
  77. package/cjs/input-group/InputGroup.js +70 -0
  78. package/cjs/input-group/InputGroupDataTestIds.js +12 -0
  79. package/cjs/input-group/exported-related/data-test-ids.js +12 -0
  80. package/cjs/input-group/exported-related/index.js +12 -0
  81. package/cjs/input-group/exported-related/theming.js +13 -0
  82. package/cjs/input-group/index.js +12 -0
  83. package/cjs/input-group/react-desc-prop-types.js +14 -0
  84. package/cjs/input-group/styled.js +47 -0
  85. package/cjs/mask-hook/hooks/index.js +0 -1
  86. package/cjs/mask-hook/hooks/usePhoneMask.js +2 -2
  87. package/cjs/mask-hook/hooks/useRegExpMask.js +0 -1
  88. package/cjs/mask-hook/index.js +0 -1
  89. package/cjs/text-input/styled/borders.js +1 -1
  90. package/esm/autocomplete/config/useAutocomplete.js +1 -3
  91. package/esm/autocomplete/parts/A11yFocusedOption.js +32 -0
  92. package/esm/autocomplete/parts/container/Container.js +39 -27
  93. package/esm/autocomplete/parts/container/styled.js +2 -2
  94. package/esm/autocomplete/parts/menu-list/MenuList.js +5 -3
  95. package/esm/autocomplete/parts/styled.js +1 -0
  96. package/esm/autocomplete/utils/listHelper.js +1 -1
  97. package/esm/checkbox/ControlledCheckbox.js +52 -36
  98. package/esm/checkbox/exported-related/data-test-ids.js +6 -0
  99. package/esm/checkbox/exported-related/index.js +2 -0
  100. package/esm/checkbox/exported-related/theming.js +8 -0
  101. package/esm/checkbox/react-desc-prop-types.js +2 -2
  102. package/esm/checkbox/styles.js +26 -15
  103. package/esm/combobox/ComboBoxCTX.js +7 -4
  104. package/esm/combobox/ComboboxDataTestids.js +1 -1
  105. package/esm/combobox/config/useComboBox.js +22 -9
  106. package/esm/combobox/index.js +2 -0
  107. package/esm/combobox/parts/A11yFocusedOption.js +15 -7
  108. package/esm/combobox/parts/A11ySelectedValues.js +0 -2
  109. package/esm/combobox/parts/DropdownIndicator.js +4 -4
  110. package/esm/combobox/parts/container/Container.js +16 -19
  111. package/esm/combobox/parts/container/styled.js +13 -6
  112. package/esm/combobox/parts/controls/Controls.js +22 -14
  113. package/esm/combobox/parts/controls/styled.js +22 -13
  114. package/esm/combobox/parts/controls/useOnPillsNavigation.js +3 -3
  115. package/esm/combobox/parts/controls-input/ControlsInput.js +3 -3
  116. package/esm/combobox/parts/controls-input/styled.js +7 -3
  117. package/esm/combobox/parts/controls-input/useControlsInput.js +5 -5
  118. package/esm/combobox/parts/controls-input/useKeyboardNavigation.js +38 -30
  119. package/esm/combobox/parts/controls-input/useMaskedOnChange.js +6 -6
  120. package/esm/combobox/parts/dropdown-indicator/DropdownIndicator.js +2 -2
  121. package/esm/combobox/parts/header-list/HeaderList.js +4 -3
  122. package/esm/combobox/parts/header-list/useHeaderListHandlers.js +11 -7
  123. package/esm/combobox/parts/menu-list/MenuList.js +10 -5
  124. package/esm/combobox/parts/menu-list/styled.js +16 -10
  125. package/esm/combobox/parts/menu-list/useItemRenderer.js +19 -17
  126. package/esm/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +1 -1
  127. package/esm/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +2 -0
  128. package/esm/combobox/parts/multi-selected-values-container/useGroupPills.js +13 -10
  129. package/esm/combobox/react-desc-prop-types.js +3 -2
  130. package/esm/combobox/theming.js +8 -0
  131. package/esm/combobox/utils/listHelper.js +12 -2
  132. package/esm/date-time-picker/config/useChangeHandlers.js +8 -12
  133. package/esm/date-time-picker/config/useControlledDateTimePicker.js +13 -9
  134. package/esm/date-time-picker/config/useFocusTracker.js +132 -0
  135. package/esm/date-time-picker/config/useGetReferences.js +41 -20
  136. package/esm/date-time-picker/config/useGlobalKeyHandlers.js +8 -12
  137. package/esm/date-time-picker/parts/ClearButton/ClearButton.js +12 -2
  138. package/esm/date-time-picker/parts/ClearButton/useClearButton.js +12 -25
  139. package/esm/date-time-picker/parts/ControlledDateTimePickerContent.js +4 -7
  140. package/esm/date-time-picker/parts/DateInputs/DDInput.js +8 -2
  141. package/esm/date-time-picker/parts/DateInputs/DateInputs.js +9 -4
  142. package/esm/date-time-picker/parts/DateInputs/MMInput.js +8 -2
  143. package/esm/date-time-picker/parts/DateInputs/YYYYInput.js +8 -2
  144. package/esm/date-time-picker/parts/DateInputs/useDateInputs.js +77 -96
  145. package/esm/date-time-picker/parts/Pickers/Calendar/CalendarHead.js +32 -6
  146. package/esm/date-time-picker/parts/Pickers/Calendar/Day.js +16 -10
  147. package/esm/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.js +12 -12
  148. package/esm/date-time-picker/parts/Pickers/Calendar/useFocusLogic.js +3 -39
  149. package/esm/date-time-picker/parts/Pickers/Calendar/useKeyboardHandlers.js +40 -73
  150. package/esm/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.js +18 -27
  151. package/esm/date-time-picker/parts/Pickers/CalendarWithTimeWheel/CalendarWithTimeWheelIconTrigger.js +1 -0
  152. package/esm/date-time-picker/parts/Pickers/CalendarWithTimeWheel/useConfigCalendarWithTimeWheelCTX.js +17 -23
  153. package/esm/date-time-picker/parts/Pickers/TimeWheel/HoursList.js +14 -8
  154. package/esm/date-time-picker/parts/Pickers/TimeWheel/MeridiemList.js +15 -9
  155. package/esm/date-time-picker/parts/Pickers/TimeWheel/MinutesList.js +14 -8
  156. package/esm/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.js +36 -230
  157. package/esm/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.js +11 -13
  158. package/esm/date-time-picker/parts/TimeInputs/HHInput.js +8 -2
  159. package/esm/date-time-picker/parts/TimeInputs/MeridiemInput.js +8 -2
  160. package/esm/date-time-picker/parts/TimeInputs/MinutesInput.js +8 -2
  161. package/esm/date-time-picker/parts/TimeInputs/TimeInputs.js +11 -6
  162. package/esm/date-time-picker/parts/TimeInputs/useTimeInputs.js +44 -74
  163. package/esm/date-time-picker/utils/constants.js +1 -7
  164. package/esm/date-time-picker/utils/hooks/useGetStartingFocusedDay.js +38 -36
  165. package/esm/index.js +5 -1
  166. package/esm/input-group/InputGroup.js +60 -0
  167. package/esm/input-group/InputGroupDataTestIds.js +8 -0
  168. package/esm/input-group/exported-related/data-test-ids.js +8 -0
  169. package/esm/input-group/exported-related/index.js +2 -0
  170. package/esm/input-group/exported-related/theming.js +8 -0
  171. package/esm/input-group/index.js +2 -0
  172. package/esm/input-group/react-desc-prop-types.js +10 -0
  173. package/esm/input-group/styled.js +36 -0
  174. package/esm/mask-hook/hooks/index.js +1 -1
  175. package/esm/mask-hook/hooks/usePhoneMask.js +2 -2
  176. package/esm/mask-hook/hooks/useRegExpMask.js +1 -1
  177. package/esm/mask-hook/index.js +1 -1
  178. package/esm/text-input/styled/borders.js +1 -1
  179. package/package.json +75 -19
  180. package/types/autocomplete/parts/A11yFocusedOption.d.ts +5 -0
  181. package/types/autocomplete/parts/container/styled.d.ts +1 -1
  182. package/types/autocomplete/parts/styled.d.ts +0 -0
  183. package/types/autocomplete/utils/listHelper.d.ts +5 -5
  184. package/types/checkbox/exported-related/data-test-ids.d.ts +4 -0
  185. package/types/checkbox/exported-related/index.d.ts +2 -0
  186. package/types/checkbox/exported-related/theming.d.ts +6 -0
  187. package/types/checkbox/react-desc-prop-types.d.ts +4 -4
  188. package/types/checkbox/styles.d.ts +6 -5
  189. package/types/combobox/ComboboxDataTestids.d.ts +1 -1
  190. package/types/combobox/index.d.ts +2 -0
  191. package/types/combobox/parts/container/styled.d.ts +1 -2
  192. package/types/combobox/parts/menu-list/styled.d.ts +1 -0
  193. package/types/combobox/react-desc-prop-types.d.ts +8 -6
  194. package/types/combobox/sharedTypes.d.ts +3 -2
  195. package/types/combobox/theming.d.ts +6 -0
  196. package/types/combobox/utils/listHelper.d.ts +1 -0
  197. package/types/date-time-picker/config/useChangeHandlers.d.ts +3 -1
  198. package/types/date-time-picker/config/useControlledDateTimePicker.d.ts +2 -5
  199. package/types/date-time-picker/config/useFocusTracker.d.ts +38 -0
  200. package/types/date-time-picker/config/useGetPropsBasedOnType.d.ts +6 -6
  201. package/types/date-time-picker/config/useGetReferences.d.ts +30 -36
  202. package/types/date-time-picker/config/useGlobalKeyHandlers.d.ts +3 -1
  203. package/types/date-time-picker/parts/DateInputs/DDInput.d.ts +2 -1
  204. package/types/date-time-picker/parts/DateInputs/MMInput.d.ts +2 -1
  205. package/types/date-time-picker/parts/DateInputs/YYYYInput.d.ts +2 -1
  206. package/types/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.d.ts +14 -0
  207. package/types/date-time-picker/parts/Pickers/Calendar/useFocusLogic.d.ts +1 -2
  208. package/types/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.d.ts +19 -0
  209. package/types/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.d.ts +0 -6
  210. package/types/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.d.ts +14 -0
  211. package/types/date-time-picker/parts/TimeInputs/HHInput.d.ts +2 -1
  212. package/types/date-time-picker/parts/TimeInputs/MeridiemInput.d.ts +2 -1
  213. package/types/date-time-picker/parts/TimeInputs/MinutesInput.d.ts +2 -1
  214. package/types/date-time-picker/propTypes.d.ts +117 -0
  215. package/types/date-time-picker/sharedTypes.d.ts +1 -1
  216. package/types/date-time-picker/utils/constants.d.ts +0 -6
  217. package/types/index.d.ts +1 -0
  218. package/types/input-group/InputGroup.d.ts +5 -0
  219. package/types/input-group/InputGroupDataTestIds.d.ts +6 -0
  220. package/types/input-group/exported-related/data-test-ids.d.ts +6 -0
  221. package/types/input-group/exported-related/index.d.ts +2 -0
  222. package/types/input-group/exported-related/theming.d.ts +6 -0
  223. package/types/input-group/index.d.ts +2 -0
  224. package/types/input-group/react-desc-prop-types.d.ts +19 -0
  225. package/types/input-group/styled.d.ts +4 -0
  226. package/types/input-group/tests/DSInputGroup.test.d.ts +1 -0
  227. package/types/mask-hook/hooks/useRegExpMask.d.ts +0 -1
  228. package/types/text-input/config/useInputText.d.ts +6 -6
  229. package/cjs/combobox/parts/menu-list/useMenuListSetFocusOption.js +0 -51
  230. package/esm/combobox/parts/menu-list/useMenuListSetFocusOption.js +0 -47
  231. package/types/combobox/parts/menu-list/useMenuListSetFocusOption.d.ts +0 -1
@@ -5,28 +5,36 @@ import 'core-js/modules/esnext.iterator.find.js';
5
5
  import { useContext, useMemo } from 'react';
6
6
  import { ComboBoxContext } from '../ComboBoxCTX.js';
7
7
  import { StyledA11ySelectedValues } from './styled.js';
8
- import { getSelectableOptions } from '../utils/listHelper.js';
8
+ import { getSelectableOptions, isSelected } from '../utils/listHelper.js';
9
9
  import { isSeparator } from '../sharedTypes.js';
10
10
 
11
11
  const A11yFocusedOption = () => {
12
12
  const {
13
13
  props: {
14
- filteredOptions
14
+ filteredOptions,
15
+ selectedValues
15
16
  },
16
17
  focusOptionIdx,
17
- showPopover
18
+ menuState
18
19
  } = useContext(ComboBoxContext);
19
20
  const selectabledOptions = getSelectableOptions(filteredOptions);
20
- const focusOption = filteredOptions.find(option => !isSeparator(option) && option.dsId === focusOptionIdx);
21
+ const focusOption = filteredOptions.find(option => option.dsId === focusOptionIdx);
22
+ const isFocusOptionSelected = (focusOption === null || focusOption === void 0 ? void 0 : focusOption.type) === 'option' && isSelected(selectedValues, focusOption);
21
23
  const focusSelectableOptionIdx = selectabledOptions.findIndex(option => option.dsId === focusOptionIdx);
24
+ const navigationContext = 'Use up and down to choose options,press enter to choose focused option, press Escape to excuse dropdown menu';
22
25
  return useMemo(() => {
23
- if (!isSeparator(focusOption) && showPopover && focusOption) return /*#__PURE__*/_jsx(StyledA11ySelectedValues, {
26
+ if (!isSeparator(focusOption) && menuState && focusOption && focusOption.type === 'option') return /*#__PURE__*/_jsx(StyledA11ySelectedValues, {
24
27
  "aria-live": "polite",
25
28
  "aria-atomic": "false",
26
29
  "aria-relevant": "additions text"
27
- }, void 0, "option ".concat(focusOption === null || focusOption === void 0 ? void 0 : focusOption.label, " focused.").concat(focusSelectableOptionIdx + 1, " of ").concat(selectabledOptions.length, " "));
30
+ }, menuState, "option ".concat(focusOption === null || focusOption === void 0 ? void 0 : focusOption.label, " ").concat(isFocusOptionSelected ? 'selected and ' : '', "focused .").concat(focusSelectableOptionIdx + 1, " of ").concat(selectabledOptions.length, ". ").concat(navigationContext, " "));
31
+ if ((focusOption === null || focusOption === void 0 ? void 0 : focusOption.type) === 'creatable') return /*#__PURE__*/_jsx(StyledA11ySelectedValues, {
32
+ "aria-live": "assertive",
33
+ "aria-atomic": "false",
34
+ "aria-relevant": "additions text"
35
+ }, menuState, "Press enter to Add: ".concat(focusOption === null || focusOption === void 0 ? void 0 : focusOption.label, ". ").concat(navigationContext));
28
36
  return null;
29
- }, [showPopover, focusOption, focusSelectableOptionIdx, selectabledOptions]);
37
+ }, [focusOption, menuState, isFocusOptionSelected, focusSelectableOptionIdx, selectabledOptions.length]);
30
38
  };
31
39
 
32
40
  export { A11yFocusedOption };
@@ -19,8 +19,6 @@ const A11ySelectedValues = () => {
19
19
  if (selectedValues.length > 0) {
20
20
  msg = "Options selected: ".concat(selectedValues.map(item => item.label).join(', '));
21
21
  }
22
-
23
- msg = 'No Options Selected';
24
22
  } else if (selectedValues) {
25
23
  msg = "Option selected: ".concat(selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.label);
26
24
  }
@@ -8,19 +8,19 @@ import { ComboBoxContext } from '../ComboBoxCTX.js';
8
8
  import { ComboboxDataTestid } from '../ComboboxDataTestids.js';
9
9
 
10
10
  var _templateObject;
11
- const StyledDropDownButton = styled(DSButtonV2)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n &:focus::after {\n border: none;\n }\n & svg {\n fill: ", ";\n }\n"])), _ref => {
11
+ const StyledDropDownButton = styled(DSButtonV2)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n &:focus::after {\n border: none;\n }\n &:hover:not(:disabled) {\n background-color: transparent;\n }\n\n & svg {\n fill: ", ";\n }\n"])), _ref => {
12
12
  let {
13
13
  theme,
14
14
  disabled
15
15
  } = _ref;
16
- return disabled ? 'red' : theme.colors.brand['700'];
16
+ return disabled ? theme.colors.neutral['400'] : theme.colors.brand['700'];
17
17
  });
18
18
  const DropdownIndicator = () => {
19
19
  const {
20
20
  props: {
21
21
  disabled
22
22
  },
23
- showPopover
23
+ menuState
24
24
  } = useContext(ComboBoxContext);
25
25
  const colorButton = useMemo(() => disabled ? ['neutral', 400] : ['brand-primary', 700], [disabled]);
26
26
  const handleOnClick = useCallback(e => {
@@ -32,7 +32,7 @@ const DropdownIndicator = () => {
32
32
  "aria-controls": "combo-listbox",
33
33
  "aria-labelledby": "combo-label",
34
34
  disabled: disabled,
35
- "aria-expanded": showPopover,
35
+ "aria-expanded": menuState,
36
36
  "aria-haspopup": "listbox",
37
37
  "aria-hidden": true,
38
38
  buttonType: "icon",
@@ -7,10 +7,10 @@ import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
7
7
  import _jsx from '@babel/runtime/helpers/esm/jsx';
8
8
  import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
9
9
  import { useContext, useCallback, useEffect, useMemo } from 'react';
10
- import { useGetGlobalAttributes } from '@elliemae/ds-props-helpers';
10
+ import { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';
11
11
  import { DSPopperJS } from '@elliemae/ds-popperjs';
12
12
  import { ComboBoxContext } from '../../ComboBoxCTX.js';
13
- import { StyledContainerInline, StyledContainerWithPopper, StyledPopperWrapper } from './styled.js';
13
+ import { StyledContainer, StyledPopperWrapper } from './styled.js';
14
14
  import { Controls } from '../controls/Controls.js';
15
15
  import { MenuList } from '../menu-list/MenuList.js';
16
16
  import { ComboboxDataTestid } from '../../ComboboxDataTestids.js';
@@ -28,23 +28,21 @@ const Container = () => {
28
28
 
29
29
  const {
30
30
  props,
31
- setShowPopover,
32
- showPopover,
31
+ setMenuState,
32
+ menuState,
33
33
  setReferenceElement,
34
34
  referenceElement
35
35
  } = useContext(ComboBoxContext);
36
36
  const {
37
37
  inline,
38
- onMenuOpen,
39
- onMenuClose,
40
38
  innerRef,
41
39
  startPlacementPreference,
42
40
  placementOrderPreference,
43
41
  withoutPortal,
44
42
  zIndex
45
43
  } = props;
46
- const StyledContainer = inline ? StyledContainerInline : StyledContainerWithPopper;
47
- const globalAttributes = useGetGlobalAttributes(props); // Removing possible collisionable props
44
+ const globalAttributes = useGetGlobalAttributes(props);
45
+ const xStyledProps = useGetXstyledProps(props); // Removing possible collisionable props
48
46
 
49
47
  const globalsAttrs = _objectWithoutProperties(globalAttributes, _excluded);
50
48
 
@@ -52,31 +50,30 @@ const Container = () => {
52
50
  e.preventDefault();
53
51
  }, []);
54
52
  const handleCloseMenu = useCallback(() => {
55
- setShowPopover(false);
53
+ setMenuState(false, 'blur');
56
54
  if (innerRef !== null && innerRef !== void 0 && innerRef.current) innerRef.current.blur();
57
- }, [innerRef, setShowPopover]);
55
+ }, [innerRef, setMenuState]);
58
56
  useEffect(() => {
59
- const closeMenuOnWindowBlur = () => setShowPopover(false);
57
+ const closeMenuOnWindowBlur = () => {
58
+ setMenuState(false, 'blur');
59
+ };
60
60
 
61
61
  window.addEventListener('blur', closeMenuOnWindowBlur);
62
62
  return () => {
63
63
  window.removeEventListener('blur', closeMenuOnWindowBlur);
64
64
  };
65
- }, [setShowPopover]);
66
- useEffect(() => {
67
- if (onMenuOpen && showPopover) onMenuOpen();else if (onMenuClose && !showPopover) onMenuClose();
68
- }, [showPopover, onMenuOpen, onMenuClose]);
69
- return useMemo(() => /*#__PURE__*/jsx(StyledContainer, _objectSpread(_objectSpread({
65
+ }, [setMenuState]);
66
+ return useMemo(() => /*#__PURE__*/jsx(StyledContainer, _objectSpread(_objectSpread(_objectSpread({
70
67
  "data-testid": ComboboxDataTestid.CONTAINER,
71
68
  ref: setReferenceElement
72
- }, globalsAttrs), {}, {
69
+ }, globalsAttrs), xStyledProps), {}, {
73
70
  children: inline ? /*#__PURE__*/jsxs(Fragment, {
74
71
  children: [_Controls || (_Controls = /*#__PURE__*/_jsx(Controls, {})), _MenuList || (_MenuList = /*#__PURE__*/_jsx(MenuList, {}))]
75
72
  }) : /*#__PURE__*/jsxs(Fragment, {
76
73
  children: [_Controls2 || (_Controls2 = /*#__PURE__*/_jsx(Controls, {})), /*#__PURE__*/_jsx(DSPopperJS, {
77
74
  customOffset: [0, 5],
78
75
  referenceElement: referenceElement,
79
- showPopover: showPopover,
76
+ showPopover: menuState,
80
77
  closeContextMenu: handleCloseMenu,
81
78
  startPlacementPreference: startPlacementPreference,
82
79
  placementOrderPreference: placementOrderPreference,
@@ -89,7 +86,7 @@ const Container = () => {
89
86
  onMouseDown: handleMouseDown
90
87
  }, void 0, _MenuList2 || (_MenuList2 = /*#__PURE__*/_jsx(MenuList, {})))))]
91
88
  })
92
- })), [inline, StyledContainer, setReferenceElement, globalsAttrs, referenceElement, showPopover, handleCloseMenu, startPlacementPreference, placementOrderPreference, withoutPortal, zIndex, handleMouseDown]);
89
+ })), [inline, setReferenceElement, globalsAttrs, referenceElement, menuState, xStyledProps, handleCloseMenu, startPlacementPreference, placementOrderPreference, withoutPortal, zIndex, handleMouseDown]);
93
90
  };
94
91
 
95
92
  export { Container };
@@ -1,15 +1,22 @@
1
1
  import _taggedTemplateLiteral from '@babel/runtime/helpers/esm/taggedTemplateLiteral';
2
2
  import { styled } from '@elliemae/ds-system';
3
+ import { DSComboBoxName, DSComboboxSlots } from '../../theming.js';
3
4
 
4
- var _templateObject, _templateObject2, _templateObject3, _templateObject4;
5
- const StyledGenericContainer = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n cursor: ", ";\n"])), _ref => {
5
+ var _templateObject, _templateObject2;
6
+ const StyledContainer = styled('div', {
7
+ name: DSComboBoxName,
8
+ slot: DSComboboxSlots.CONTAINER
9
+ })(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n cursor: ", ";\n"])), _ref => {
6
10
  let {
7
11
  disabled
8
12
  } = _ref;
9
13
  return disabled ? 'not-allowed' : 'default';
10
14
  });
11
- const StyledContainerWithPopper = styled(StyledGenericContainer)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: 100%;\n height: 28px;\n"])));
12
- const StyledContainerInline = styled(StyledGenericContainer)(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n width: 100%;\n"])));
13
- const StyledPopperWrapper = styled(StyledGenericContainer)(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n overflow: auto;\n"])));
15
+ const StyledPopperWrapper = styled('div')(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n cursor: ", ";\n overflow: auto;\n"])), _ref2 => {
16
+ let {
17
+ disabled
18
+ } = _ref2;
19
+ return disabled ? 'not-allowed' : 'default';
20
+ });
14
21
 
15
- export { StyledContainerInline, StyledContainerWithPopper, StyledPopperWrapper };
22
+ export { StyledContainer, StyledPopperWrapper };
@@ -4,6 +4,7 @@ import { DropdownIndicator } from '../DropdownIndicator.js';
4
4
  import { ComboboxDataTestid } from '../../ComboboxDataTestids.js';
5
5
  import { ComboBoxContext } from '../../ComboBoxCTX.js';
6
6
  import { StyledControlsWrapper, StyledSelection, StyledHeaderActionsWrapper, StyleHeaderActionsSeparator } from './styled.js';
7
+ import { scrollIfNeeded } from '../../utils/listHelper.js';
7
8
  import { MultiSelectedValuesContainer } from '../multi-selected-values-container/MultiSelectedValuesContainer.js';
8
9
  import { ControlsInput } from '../controls-input/ControlsInput.js';
9
10
  import { useOnPillsNavigation } from './useOnPillsNavigation.js';
@@ -12,7 +13,7 @@ import { A11ySelectedValues } from '../A11ySelectedValues.js';
12
13
  import { RemovableSelectedValuePill } from '../multi-selected-values-container/RemovableSelectedValuePill.js';
13
14
  import { jsxs } from 'react/jsx-runtime';
14
15
 
15
- var _A11ySelectedValues, _A11yFocusedOption, _MultiSelectedValuesC, _ControlsInput, _DropdownIndicator;
16
+ var _A11ySelectedValues, _MultiSelectedValuesC, _A11yFocusedOption, _ControlsInput, _DropdownIndicator;
16
17
  const Controls = () => {
17
18
  const {
18
19
  props: {
@@ -24,11 +25,12 @@ const Controls = () => {
24
25
  innerRef
25
26
  },
26
27
  selectedOptionsRef,
27
- setShowPopover,
28
+ setMenuState,
29
+ setFocusOptionIdx,
28
30
  hasFocus,
31
+ listRef,
29
32
  focusOptionIdx,
30
- scrollOptionIntoView,
31
- showPopover,
33
+ menuState,
32
34
  controlsWrapperRef
33
35
  } = useContext(ComboBoxContext);
34
36
  const handleOnClick = useCallback(() => {
@@ -36,28 +38,34 @@ const Controls = () => {
36
38
 
37
39
  if (disabled) return;
38
40
 
39
- if (hasFocus && showPopover && !inline) {
41
+ if (hasFocus && menuState && !inline) {
40
42
  var _innerRef$current;
41
43
 
42
- setShowPopover(false);
44
+ setMenuState(false);
45
+ setFocusOptionIdx('');
43
46
  (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.blur();
44
47
  return;
45
48
  }
46
49
 
47
50
  (_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 ? void 0 : _innerRef$current2.focus();
48
- setShowPopover(true); // eslint-disable-next-line react-hooks/exhaustive-deps
49
- }, [disabled, hasFocus, showPopover, inline, innerRef, setShowPopover, focusOptionIdx]); // this callback prevent to toggle the menu when clicking or removing pills
51
+ setMenuState(true);
52
+ window.requestAnimationFrame(() => {
53
+ window.requestAnimationFrame(() => {
54
+ if (listRef.current) scrollIfNeeded(listRef.current);
55
+ });
56
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
57
+ }, [disabled, listRef, hasFocus, menuState, inline, innerRef, setMenuState, focusOptionIdx]); // this callback prevent to toggle the menu when clicking or removing pills
50
58
 
51
59
  const handleOnPillsClick = useCallback(e => {
52
- if (showPopover || disabled) {
60
+ if (menuState || disabled) {
53
61
  e.stopPropagation();
54
62
  } else {
55
63
  var _innerRef$current3;
56
64
 
57
65
  (_innerRef$current3 = innerRef.current) === null || _innerRef$current3 === void 0 ? void 0 : _innerRef$current3.focus();
58
- setShowPopover(true);
66
+ setMenuState(true);
59
67
  }
60
- }, [showPopover, innerRef, disabled, setShowPopover]); // callback to prevent onBlur on the input when clicking in all the wrapper
68
+ }, [menuState, innerRef, disabled, setMenuState]); // callback to prevent onBlur on the input when clicking in all the wrapper
61
69
 
62
70
  const handleOnMouseDown = useCallback(e => {
63
71
  if (document.activeElement === innerRef.current || inline) {
@@ -82,14 +90,14 @@ const Controls = () => {
82
90
  children: [!inline && /*#__PURE__*/jsxs(StyledSelection, {
83
91
  ref: selectedOptionsRef,
84
92
  onClick: handleOnPillsClick,
85
- children: [_A11ySelectedValues || (_A11ySelectedValues = /*#__PURE__*/_jsx(A11ySelectedValues, {})), _A11yFocusedOption || (_A11yFocusedOption = /*#__PURE__*/_jsx(A11yFocusedOption, {})), Array.isArray(selectedValues) ? _MultiSelectedValuesC || (_MultiSelectedValuesC = /*#__PURE__*/_jsx(MultiSelectedValuesContainer, {})) : /*#__PURE__*/_jsx("div", {
93
+ children: [_A11ySelectedValues || (_A11ySelectedValues = /*#__PURE__*/_jsx(A11ySelectedValues, {})), Array.isArray(selectedValues) ? _MultiSelectedValuesC || (_MultiSelectedValuesC = /*#__PURE__*/_jsx(MultiSelectedValuesContainer, {})) : /*#__PURE__*/_jsx("div", {
86
94
  "data-testid": ComboboxDataTestid.SELECTED_VALUES
87
95
  }, void 0, selectedValues && /*#__PURE__*/_jsx(RemovableSelectedValuePill, {
88
96
  pill: selectedValues
89
97
  }))]
90
- }), _ControlsInput || (_ControlsInput = /*#__PURE__*/_jsx(ControlsInput, {})), !inline && /*#__PURE__*/_jsx(StyledHeaderActionsWrapper, {
98
+ }), _A11yFocusedOption || (_A11yFocusedOption = /*#__PURE__*/_jsx(A11yFocusedOption, {})), _ControlsInput || (_ControlsInput = /*#__PURE__*/_jsx(ControlsInput, {})), !inline && /*#__PURE__*/_jsx(StyledHeaderActionsWrapper, {
91
99
  justifyContent: "center",
92
- cols: ['auto', 'auto']
100
+ cols: ['min-content', 'min-content']
93
101
  }, void 0, /*#__PURE__*/_jsx(StyleHeaderActionsSeparator, {
94
102
  disabled: disabled
95
103
  }), _DropdownIndicator || (_DropdownIndicator = /*#__PURE__*/_jsx(DropdownIndicator, {})))]
@@ -1,6 +1,7 @@
1
1
  import _taggedTemplateLiteral from '@babel/runtime/helpers/esm/taggedTemplateLiteral';
2
2
  import { css, styled } from '@elliemae/ds-system';
3
3
  import { Grid } from '@elliemae/ds-grid';
4
+ import { DSComboBoxName, DSComboboxSlots } from '../../theming.js';
4
5
 
5
6
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8;
6
7
  const normalBorder = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n"])), _ref => {
@@ -10,39 +11,47 @@ const normalBorder = css(_templateObject || (_templateObject = _taggedTemplateLi
10
11
  } = _ref;
11
12
  return hasError ? theme.colors.danger[900] : theme.colors.neutral[400];
12
13
  });
13
- const focusBorder = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n border: 2px solid ", ";\n"])), _ref2 => {
14
+ const focusBorder = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n outline: 2px solid ", ";\n outline-offset: -2px;\n"])), _ref2 => {
14
15
  let {
15
16
  theme
16
17
  } = _ref2;
17
18
  return theme.colors.brand[700];
18
19
  });
19
- const afterStyle = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: block;\n content: ' ';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border-radius: 2px;\n pointer-events: none;\n z-index: 7;\n"])));
20
- const StyledControlsWrapper = styled(Grid)(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n background: ", ";\n position: relative;\n border-radius: 2px;\n min-width: ", ";\n align-items: center;\n align-content: center;\n height: 28px;\n padding-left: 8px;\n margin: ", ";\n &::after {\n ", "\n ", "\n }\n\n &:focus-within {\n &::after {\n ", "\n ", "\n }\n }\n"])), _ref3 => {
20
+ const hoverBorder = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n"])), _ref3 => {
21
21
  let {
22
- disabled,
23
22
  theme
24
23
  } = _ref3;
24
+ return theme.colors.brand[700];
25
+ });
26
+ const StyledControlsWrapper = styled(Grid, {
27
+ name: DSComboBoxName,
28
+ slot: DSComboboxSlots.INPUT_WRAPPER
29
+ })(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n background: ", ";\n position: relative;\n border-radius: 2px;\n min-width: ", ";\n align-items: center;\n align-content: center;\n height: 28px;\n padding-left: 8px;\n margin: ", ";\n ", "\n &:hover {\n ", "\n }\n &:focus-within {\n ", "\n }\n"])), _ref4 => {
30
+ let {
31
+ disabled,
32
+ theme
33
+ } = _ref4;
25
34
  return disabled ? theme.colors.neutral['080'] : '#ffffff';
26
- }, _ref4 => {
35
+ }, _ref5 => {
27
36
  let {
28
37
  minWidth,
29
38
  inline
30
- } = _ref4;
39
+ } = _ref5;
31
40
  return inline || !minWidth ? '' : "".concat(minWidth, "px");
32
- }, _ref5 => {
41
+ }, _ref6 => {
33
42
  let {
34
43
  inline
35
- } = _ref5;
36
- return inline ? '10px 16px' : 'none';
37
- }, afterStyle, normalBorder, afterStyle, focusBorder);
38
- const StyledSelection = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n font-size: 13px;\n margin-right: 3px;\n line-height: 13px;\n display: flex;\n"])));
44
+ } = _ref6;
45
+ return inline ? '10px 16px' : '';
46
+ }, normalBorder, hoverBorder, focusBorder);
47
+ const StyledSelection = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n font-size: 13px;\n margin-right: 3px;\n display: flex;\n"])));
39
48
  const StyledHeaderActionsWrapper = styled(Grid)(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n height: 100%;\n .em-ds-button--text:focus::after {\n border: none;\n }\n"])));
40
49
  const StyleDropdownIndicator = styled.div(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral([""])));
41
- const StyleHeaderActionsSeparator = styled.span(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n align-self: stretch;\n margin: 4px 0px;\n width: 1px;\n background-color: ", ";\n"])), _ref6 => {
50
+ const StyleHeaderActionsSeparator = styled.span(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n align-self: stretch;\n margin: 4px 0px;\n width: 1px;\n background-color: ", ";\n"])), _ref7 => {
42
51
  let {
43
52
  theme,
44
53
  disabled
45
- } = _ref6;
54
+ } = _ref7;
46
55
  return disabled ? theme.colors.neutral['400'] : theme.colors.neutral['500'];
47
56
  });
48
57
 
@@ -9,7 +9,7 @@ const useOnPillsNavigation = () => {
9
9
  },
10
10
  inputValue,
11
11
  hasFocus,
12
- setShowPopover,
12
+ setMenuState,
13
13
  selectedOptionsRef
14
14
  } = useContext(ComboBoxContext); // todo: constant must be defined on pills component
15
15
 
@@ -20,7 +20,7 @@ const useOnPillsNavigation = () => {
20
20
  var _innerRef$current;
21
21
 
22
22
  (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.focus();
23
- setShowPopover(true);
23
+ setMenuState(true, 'open', e);
24
24
  return;
25
25
  }
26
26
 
@@ -43,7 +43,7 @@ const useOnPillsNavigation = () => {
43
43
  (_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 ? void 0 : _innerRef$current2.focus();
44
44
  }
45
45
  }
46
- }, [inputValue, hasFocus, innerRef, selectedOptionsRef, setShowPopover]);
46
+ }, [inputValue, innerRef, setMenuState, selectedOptionsRef, hasFocus]);
47
47
  return {
48
48
  onKeyDownPills
49
49
  };
@@ -19,7 +19,7 @@ const ControlsInput = () => {
19
19
  },
20
20
  focusOptionIdx,
21
21
  inputValue,
22
- showPopover
22
+ menuState
23
23
  } = useContext(ComboBoxContext);
24
24
  const {
25
25
  onInputKeyDown
@@ -44,8 +44,8 @@ const ControlsInput = () => {
44
44
  placeholder: placeholder,
45
45
  "aria-controls": "combo-listbox",
46
46
  "aria-activedescendant": focusOptionIdx,
47
- "aria-expanded": showPopover,
48
- "aria-haspopup": "true",
47
+ "aria-expanded": menuState,
48
+ "aria-haspopup": "listbox",
49
49
  "aria-describedby": "combobox-selected-items",
50
50
  role: "combobox",
51
51
  disabled: disabled,
@@ -1,15 +1,19 @@
1
1
  import _taggedTemplateLiteral from '@babel/runtime/helpers/esm/taggedTemplateLiteral';
2
2
  import { styled } from '@elliemae/ds-system';
3
+ import { DSComboBoxName, DSComboboxSlots } from '../../theming.js';
3
4
 
4
5
  var _templateObject, _templateObject2, _templateObject3, _templateObject4;
5
- const StyledInput = styled.input(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-size: 13px;\n line-height: 13px;\n border: none;\n padding: 0;\n outline: none;\n color: ", ";\n &:focus {\n outline: none;\n }\n ", "\n &::placeholder {\n color: transparent;\n }\n"])), props => props.theme.colors.neutral[700], _ref => {
6
+ const StyledInput = styled('input', {
7
+ name: DSComboBoxName,
8
+ slot: DSComboboxSlots.INPUT
9
+ })(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-size: 13px;\n line-height: 13px;\n border: none;\n padding: 0;\n outline: none;\n color: ", ";\n &:focus {\n outline: none;\n }\n ", "\n &::placeholder {\n color: transparent;\n }\n"])), props => props.theme.colors.neutral[700], _ref => {
6
10
  let {
7
11
  withoutCaret
8
12
  } = _ref;
9
13
  return withoutCaret && 'caret-color: transparent;';
10
14
  });
11
- const StyledInputPlaceHolder = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n font-style: italic;\n color: ", ";\n position: absolute;\n display: flex;\n align-items: center;\n width: 100%;\n user-select: none;\n height: 28px;\n & span {\n line-height: 13px;\n }\n"])), props => props.theme.colors.neutral[500]);
15
+ const StyledInputPlaceHolder = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n font-style: italic;\n color: ", ";\n position: absolute;\n display: flex;\n align-items: center;\n width: 100%;\n user-select: none;\n height: 28px;\n font-size: 13px;\n & span::after {\n content: '';\n padding: 1px;\n }\n"])), props => props.theme.colors.neutral[500]);
12
16
  const StyledInputWidthReference = styled.span(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n visibility: hidden;\n position: absolute;\n top: -9999px;\n"])));
13
- const StyledInputWrapper = styled.div(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n position: relative;\n flex: 1;\n margin-right: 5px;\n display: flex;\n align-items: center;\n"])));
17
+ const StyledInputWrapper = styled('div')(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n position: relative;\n align-items: center;\n display: flex;\n"])));
14
18
 
15
19
  export { StyledInput, StyledInputPlaceHolder, StyledInputWidthReference, StyledInputWrapper };
@@ -15,8 +15,8 @@ const useControlsInput = () => {
15
15
  },
16
16
  setHasFocus,
17
17
  inputValue,
18
- setInputValue,
19
- setShowSelectedOptions
18
+ setMenuState,
19
+ setInputValue
20
20
  } = useContext(ComboBoxContext);
21
21
  const [width, setWidth] = useState(1); // use span reference to calculate the real width for the input
22
22
 
@@ -33,9 +33,9 @@ const useControlsInput = () => {
33
33
  const handleOnChange = useMaskedOnChange();
34
34
  const handleOnBlur = useCallback(() => {
35
35
  setInputValue('');
36
- if (onFilter) onFilter(allOptions, inputValue);
37
- setHasFocus(false); // setShowSelectedOptions(false);
38
- }, [setInputValue, onFilter, allOptions, inputValue, setHasFocus, setShowSelectedOptions]);
36
+ if (onFilter) onFilter(allOptions);
37
+ setHasFocus(false);
38
+ }, [setInputValue, onFilter, allOptions, setHasFocus]);
39
39
  const handleOnFocus = useCallback(() => {
40
40
  setHasFocus(true);
41
41
  }, [setHasFocus]);
@@ -5,7 +5,7 @@ import 'core-js/modules/esnext.async-iterator.filter.js';
5
5
  import 'core-js/modules/esnext.iterator.filter.js';
6
6
  import { useContext, useCallback } from 'react';
7
7
  import { ComboBoxContext } from '../../ComboBoxCTX.js';
8
- import { getOptions, getSuggestedValueOnChange, findInCircularList, getLastValueSelected } from '../../utils/listHelper.js';
8
+ import { getOptions, scrollIfNeeded, getSuggestedValueOnChange, findInCircularList, getLastValueSelected } from '../../utils/listHelper.js';
9
9
  import { MENU_OPTION_TYPES, INTERNAL_MENU_OPTION_TYPES } from '../../constants.js';
10
10
 
11
11
  const isOptionFocuseable = opt => !['section', 'separator'].includes(opt.type) && !opt.disabled;
@@ -26,11 +26,12 @@ const useKeyboardNavigation = () => {
26
26
  withoutPortal
27
27
  },
28
28
  inputValue,
29
- showPopover,
29
+ menuState,
30
30
  focusOptionIdx,
31
+ listRef,
31
32
  selectAllCheckboxRef,
32
33
  toggleSelectionButtonRef,
33
- setShowPopover,
34
+ setMenuState,
34
35
  setInputValue,
35
36
  scrollOptionIntoView,
36
37
  setFocusOptionIdx
@@ -45,8 +46,11 @@ const useKeyboardNavigation = () => {
45
46
  // =============================================================================
46
47
  if (onKeyDown && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === MENU_OPTION_TYPES.OPTION) onKeyDown(e, currentItem);
47
48
 
48
- if (['ArrowDown', 'ArrowUp', 'Enter', 'Spacebar'].includes(e.key) || e.keyCode >= 48 && e.keyCode <= 90) {
49
- setShowPopover(true);
49
+ if ((['ArrowDown', 'ArrowUp', 'Enter', 'Spacebar'].includes(e.key) || e.keyCode >= 48 && e.keyCode <= 90) && !menuState) {
50
+ setMenuState(true);
51
+ window.requestAnimationFrame(() => {
52
+ if (listRef.current) scrollIfNeeded(listRef.current);
53
+ });
50
54
  } // =============================================================================
51
55
  // ESCAPE
52
56
  // =============================================================================
@@ -60,14 +64,14 @@ const useKeyboardNavigation = () => {
60
64
  setInputValue('');
61
65
  }
62
66
 
63
- if (!inline) setShowPopover(false);
67
+ if (!inline) setMenuState(false, 'close', e);
64
68
  } // =============================================================================
65
69
  // ENTER KEY TO CREATE ELEMENTS
66
70
  // =============================================================================
67
71
 
68
72
 
69
73
  if (e.key === 'Enter' && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === INTERNAL_MENU_OPTION_TYPES.CREATABLE && onCreate) {
70
- onCreate(inputValue); //blank active item to force search last one
74
+ onCreate(inputValue); // blank active item to force search last one
71
75
 
72
76
  setFocusOptionIdx('');
73
77
  if (onFilter) onFilter(allOptions, '');
@@ -82,12 +86,12 @@ const useKeyboardNavigation = () => {
82
86
  e.preventDefault();
83
87
  e.stopPropagation();
84
88
 
85
- if (focusOptionIdx !== '' && (showPopover || inline) && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === MENU_OPTION_TYPES.OPTION && !currentItem.disabled) {
89
+ if (focusOptionIdx !== '' && (menuState || inline) && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === MENU_OPTION_TYPES.OPTION && !currentItem.disabled) {
86
90
  if (onFilter) onFilter(allOptions, '');
87
91
  setInputValue('');
88
92
 
89
93
  if (!multiple) {
90
- setShowPopover(false);
94
+ setMenuState(false, 'selectOption', e);
91
95
  }
92
96
 
93
97
  onChange(getSuggestedValueOnChange(currentItem, selectedValues), currentItem, e);
@@ -95,7 +99,7 @@ const useKeyboardNavigation = () => {
95
99
  }
96
100
 
97
101
  if (e.key === 'Enter' && e.altKey) {
98
- setShowPopover(false);
102
+ setMenuState(false, 'selectOption', e);
99
103
  }
100
104
 
101
105
  if (e.key === 'a' && e.ctrlKey && multiple && onSelectAll) {
@@ -109,10 +113,13 @@ const useKeyboardNavigation = () => {
109
113
  e.preventDefault();
110
114
  e.stopPropagation();
111
115
 
112
- if ((showPopover || inline) && selectableOptions.length) {
113
- const nextItemIndex = findInCircularList(filteredOptions, currentItemIndex, isOptionFocuseable);
114
- setFocusOptionIdx(filteredOptions[nextItemIndex].dsId);
115
- scrollOptionIntoView(filteredOptions[nextItemIndex].dsId);
116
+ if ((menuState || inline) && selectableOptions.length) {
117
+ const nextItemIndexIndex = findInCircularList(filteredOptions, currentItemIndex, isOptionFocuseable);
118
+
119
+ if (nextItemIndexIndex > -1) {
120
+ setFocusOptionIdx(filteredOptions[nextItemIndexIndex].dsId);
121
+ scrollOptionIntoView(filteredOptions[nextItemIndexIndex].dsId);
122
+ }
116
123
  }
117
124
  }
118
125
 
@@ -122,16 +129,19 @@ const useKeyboardNavigation = () => {
122
129
  if (!selectableOptions.length) return;
123
130
  const prevItemIndex = findInCircularList(filteredOptions, currentItemIndex, isOptionFocuseable, -1);
124
131
 
125
- if (showPopover || inline) {
126
- setFocusOptionIdx(filteredOptions[prevItemIndex].dsId);
127
- scrollOptionIntoView(filteredOptions[prevItemIndex].dsId);
128
- } else {
129
- setShowPopover(true);
130
- setTimeout(() => {
131
- const prevItem = findInCircularList(filteredOptions, 0, isOptionFocuseable, -1);
132
- setFocusOptionIdx(filteredOptions[prevItem].dsId);
133
- scrollOptionIntoView(filteredOptions[prevItem].dsId);
134
- });
132
+ if (prevItemIndex > -1) {
133
+ if (menuState || inline) {
134
+ setFocusOptionIdx(filteredOptions[prevItemIndex].dsId);
135
+ scrollOptionIntoView(filteredOptions[prevItemIndex].dsId);
136
+ } else {
137
+ // open menu and search last item to focused
138
+ setMenuState(true, 'open', e);
139
+ const lastItemIndex = findInCircularList(filteredOptions, 0, isOptionFocuseable, -1);
140
+ setFocusOptionIdx(filteredOptions[lastItemIndex].dsId);
141
+ setTimeout(() => {
142
+ scrollOptionIntoView(filteredOptions[lastItemIndex].dsId);
143
+ });
144
+ }
135
145
  }
136
146
  } // =============================================================================
137
147
  // BACKSPACE
@@ -148,7 +158,7 @@ const useKeyboardNavigation = () => {
148
158
  if (onFilter) onFilter(allOptions, inputValue);
149
159
  }
150
160
 
151
- if (e.key === 'Tab' && !inline && !withoutPortal) {
161
+ if (e.key === 'Tab' && !inline && menuState) {
152
162
  var _selectAllCheckboxRef;
153
163
 
154
164
  const element = (_selectAllCheckboxRef = selectAllCheckboxRef.current) !== null && _selectAllCheckboxRef !== void 0 ? _selectAllCheckboxRef : toggleSelectionButtonRef.current;
@@ -156,14 +166,12 @@ const useKeyboardNavigation = () => {
156
166
  if (element) {
157
167
  e.preventDefault();
158
168
  element.focus();
169
+ } else {
170
+ setMenuState(false, 'blur', e);
159
171
  }
160
172
  }
161
-
162
- if (e.key === 'Tab' && !multiple && showPopover) {
163
- setShowPopover(false);
164
- }
165
173
  }, // eslint-disable-next-line react-hooks/exhaustive-deps
166
- [onKeyDown, currentItem, onCreate, multiple, inputValue, inline, withoutPortal, setShowPopover, onCancel, onFilter, setInputValue, focusOptionIdx, showPopover, selectableOptions.length, filteredOptions, currentItemIndex, setFocusOptionIdx, selectedValues, onChange, selectAllCheckboxRef, toggleSelectionButtonRef]);
174
+ [onKeyDown, currentItem, onCreate, multiple, inputValue, inline, withoutPortal, setMenuState, onCancel, onFilter, setInputValue, listRef, focusOptionIdx, menuState, selectableOptions.length, filteredOptions, currentItemIndex, setFocusOptionIdx, selectedValues, onChange, selectAllCheckboxRef, toggleSelectionButtonRef]);
167
175
  return {
168
176
  onInputKeyDown
169
177
  };