@elliemae/ds-controlled-form 2.4.2-rc.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 (168) hide show
  1. package/cjs/autocomplete/parts/A11yFocusedOption.js +43 -0
  2. package/cjs/autocomplete/parts/container/Container.js +36 -24
  3. package/cjs/autocomplete/parts/container/styled.js +2 -2
  4. package/cjs/autocomplete/parts/menu-list/MenuList.js +4 -2
  5. package/cjs/autocomplete/parts/styled.js +2 -0
  6. package/cjs/autocomplete/utils/listHelper.js +1 -1
  7. package/cjs/checkbox/ControlledCheckbox.js +1 -1
  8. package/cjs/checkbox/react-desc-prop-types.js +2 -1
  9. package/cjs/checkbox/styles.js +4 -2
  10. package/cjs/combobox/ComboBoxCTX.js +6 -3
  11. package/cjs/combobox/config/useComboBox.js +15 -4
  12. package/cjs/combobox/parts/A11yFocusedOption.js +14 -6
  13. package/cjs/combobox/parts/A11ySelectedValues.js +0 -2
  14. package/cjs/combobox/parts/DropdownIndicator.js +2 -2
  15. package/cjs/combobox/parts/container/Container.js +10 -13
  16. package/cjs/combobox/parts/controls/Controls.js +16 -18
  17. package/cjs/combobox/parts/controls/useOnPillsNavigation.js +3 -3
  18. package/cjs/combobox/parts/controls-input/ControlsInput.js +2 -2
  19. package/cjs/combobox/parts/controls-input/useControlsInput.js +3 -2
  20. package/cjs/combobox/parts/controls-input/useKeyboardNavigation.js +16 -23
  21. package/cjs/combobox/parts/controls-input/useMaskedOnChange.js +6 -6
  22. package/cjs/combobox/parts/dropdown-indicator/DropdownIndicator.js +2 -2
  23. package/cjs/combobox/parts/header-list/useHeaderListHandlers.js +3 -3
  24. package/cjs/combobox/parts/menu-list/MenuList.js +7 -5
  25. package/cjs/combobox/parts/menu-list/styled.js +5 -3
  26. package/cjs/combobox/parts/menu-list/useItemRenderer.js +16 -15
  27. package/cjs/combobox/react-desc-prop-types.js +3 -2
  28. package/cjs/combobox/utils/listHelper.js +10 -0
  29. package/cjs/date-time-picker/config/useChangeHandlers.js +8 -12
  30. package/cjs/date-time-picker/config/useControlledDateTimePicker.js +13 -9
  31. package/cjs/date-time-picker/config/useFocusTracker.js +136 -0
  32. package/cjs/date-time-picker/config/useGetReferences.js +40 -19
  33. package/cjs/date-time-picker/config/useGlobalKeyHandlers.js +8 -12
  34. package/cjs/date-time-picker/parts/ClearButton/ClearButton.js +12 -2
  35. package/cjs/date-time-picker/parts/ClearButton/useClearButton.js +12 -25
  36. package/cjs/date-time-picker/parts/ControlledDateTimePickerContent.js +4 -7
  37. package/cjs/date-time-picker/parts/DateInputs/DDInput.js +8 -2
  38. package/cjs/date-time-picker/parts/DateInputs/DateInputs.js +9 -4
  39. package/cjs/date-time-picker/parts/DateInputs/MMInput.js +8 -2
  40. package/cjs/date-time-picker/parts/DateInputs/YYYYInput.js +8 -2
  41. package/cjs/date-time-picker/parts/DateInputs/useDateInputs.js +76 -95
  42. package/cjs/date-time-picker/parts/Pickers/Calendar/CalendarHead.js +31 -5
  43. package/cjs/date-time-picker/parts/Pickers/Calendar/Day.js +16 -10
  44. package/cjs/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.js +12 -12
  45. package/cjs/date-time-picker/parts/Pickers/Calendar/useFocusLogic.js +2 -38
  46. package/cjs/date-time-picker/parts/Pickers/Calendar/useKeyboardHandlers.js +40 -73
  47. package/cjs/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.js +18 -27
  48. package/cjs/date-time-picker/parts/Pickers/CalendarWithTimeWheel/CalendarWithTimeWheelIconTrigger.js +1 -0
  49. package/cjs/date-time-picker/parts/Pickers/CalendarWithTimeWheel/useConfigCalendarWithTimeWheelCTX.js +17 -23
  50. package/cjs/date-time-picker/parts/Pickers/TimeWheel/HoursList.js +13 -7
  51. package/cjs/date-time-picker/parts/Pickers/TimeWheel/MeridiemList.js +14 -8
  52. package/cjs/date-time-picker/parts/Pickers/TimeWheel/MinutesList.js +13 -7
  53. package/cjs/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.js +36 -230
  54. package/cjs/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.js +11 -13
  55. package/cjs/date-time-picker/parts/TimeInputs/HHInput.js +8 -2
  56. package/cjs/date-time-picker/parts/TimeInputs/MeridiemInput.js +8 -2
  57. package/cjs/date-time-picker/parts/TimeInputs/MinutesInput.js +8 -2
  58. package/cjs/date-time-picker/parts/TimeInputs/TimeInputs.js +11 -6
  59. package/cjs/date-time-picker/parts/TimeInputs/useTimeInputs.js +44 -74
  60. package/cjs/date-time-picker/utils/constants.js +0 -12
  61. package/cjs/date-time-picker/utils/hooks/useGetStartingFocusedDay.js +38 -36
  62. package/cjs/input-group/InputGroup.js +8 -7
  63. package/cjs/input-group/exported-related/data-test-ids.js +12 -0
  64. package/cjs/input-group/exported-related/index.js +12 -0
  65. package/cjs/input-group/exported-related/theming.js +13 -0
  66. package/cjs/input-group/styled.js +21 -20
  67. package/esm/autocomplete/parts/A11yFocusedOption.js +32 -0
  68. package/esm/autocomplete/parts/container/Container.js +39 -27
  69. package/esm/autocomplete/parts/container/styled.js +2 -2
  70. package/esm/autocomplete/parts/menu-list/MenuList.js +5 -3
  71. package/esm/autocomplete/parts/styled.js +1 -0
  72. package/esm/autocomplete/utils/listHelper.js +1 -1
  73. package/esm/checkbox/ControlledCheckbox.js +2 -2
  74. package/esm/checkbox/react-desc-prop-types.js +2 -1
  75. package/esm/checkbox/styles.js +4 -3
  76. package/esm/combobox/ComboBoxCTX.js +6 -3
  77. package/esm/combobox/config/useComboBox.js +16 -5
  78. package/esm/combobox/parts/A11yFocusedOption.js +15 -7
  79. package/esm/combobox/parts/A11ySelectedValues.js +0 -2
  80. package/esm/combobox/parts/DropdownIndicator.js +2 -2
  81. package/esm/combobox/parts/container/Container.js +10 -13
  82. package/esm/combobox/parts/controls/Controls.js +16 -18
  83. package/esm/combobox/parts/controls/useOnPillsNavigation.js +3 -3
  84. package/esm/combobox/parts/controls-input/ControlsInput.js +2 -2
  85. package/esm/combobox/parts/controls-input/useControlsInput.js +3 -2
  86. package/esm/combobox/parts/controls-input/useKeyboardNavigation.js +17 -24
  87. package/esm/combobox/parts/controls-input/useMaskedOnChange.js +6 -6
  88. package/esm/combobox/parts/dropdown-indicator/DropdownIndicator.js +2 -2
  89. package/esm/combobox/parts/header-list/useHeaderListHandlers.js +3 -3
  90. package/esm/combobox/parts/menu-list/MenuList.js +7 -5
  91. package/esm/combobox/parts/menu-list/styled.js +5 -4
  92. package/esm/combobox/parts/menu-list/useItemRenderer.js +18 -17
  93. package/esm/combobox/react-desc-prop-types.js +3 -2
  94. package/esm/combobox/utils/listHelper.js +10 -1
  95. package/esm/date-time-picker/config/useChangeHandlers.js +8 -12
  96. package/esm/date-time-picker/config/useControlledDateTimePicker.js +13 -9
  97. package/esm/date-time-picker/config/useFocusTracker.js +132 -0
  98. package/esm/date-time-picker/config/useGetReferences.js +41 -20
  99. package/esm/date-time-picker/config/useGlobalKeyHandlers.js +8 -12
  100. package/esm/date-time-picker/parts/ClearButton/ClearButton.js +12 -2
  101. package/esm/date-time-picker/parts/ClearButton/useClearButton.js +12 -25
  102. package/esm/date-time-picker/parts/ControlledDateTimePickerContent.js +4 -7
  103. package/esm/date-time-picker/parts/DateInputs/DDInput.js +8 -2
  104. package/esm/date-time-picker/parts/DateInputs/DateInputs.js +9 -4
  105. package/esm/date-time-picker/parts/DateInputs/MMInput.js +8 -2
  106. package/esm/date-time-picker/parts/DateInputs/YYYYInput.js +8 -2
  107. package/esm/date-time-picker/parts/DateInputs/useDateInputs.js +77 -96
  108. package/esm/date-time-picker/parts/Pickers/Calendar/CalendarHead.js +32 -6
  109. package/esm/date-time-picker/parts/Pickers/Calendar/Day.js +16 -10
  110. package/esm/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.js +12 -12
  111. package/esm/date-time-picker/parts/Pickers/Calendar/useFocusLogic.js +3 -39
  112. package/esm/date-time-picker/parts/Pickers/Calendar/useKeyboardHandlers.js +40 -73
  113. package/esm/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.js +18 -27
  114. package/esm/date-time-picker/parts/Pickers/CalendarWithTimeWheel/CalendarWithTimeWheelIconTrigger.js +1 -0
  115. package/esm/date-time-picker/parts/Pickers/CalendarWithTimeWheel/useConfigCalendarWithTimeWheelCTX.js +17 -23
  116. package/esm/date-time-picker/parts/Pickers/TimeWheel/HoursList.js +14 -8
  117. package/esm/date-time-picker/parts/Pickers/TimeWheel/MeridiemList.js +15 -9
  118. package/esm/date-time-picker/parts/Pickers/TimeWheel/MinutesList.js +14 -8
  119. package/esm/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.js +36 -230
  120. package/esm/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.js +11 -13
  121. package/esm/date-time-picker/parts/TimeInputs/HHInput.js +8 -2
  122. package/esm/date-time-picker/parts/TimeInputs/MeridiemInput.js +8 -2
  123. package/esm/date-time-picker/parts/TimeInputs/MinutesInput.js +8 -2
  124. package/esm/date-time-picker/parts/TimeInputs/TimeInputs.js +11 -6
  125. package/esm/date-time-picker/parts/TimeInputs/useTimeInputs.js +44 -74
  126. package/esm/date-time-picker/utils/constants.js +1 -7
  127. package/esm/date-time-picker/utils/hooks/useGetStartingFocusedDay.js +38 -36
  128. package/esm/input-group/InputGroup.js +5 -4
  129. package/esm/input-group/exported-related/data-test-ids.js +8 -0
  130. package/esm/input-group/exported-related/index.js +2 -0
  131. package/esm/input-group/exported-related/theming.js +8 -0
  132. package/esm/input-group/styled.js +18 -17
  133. package/package.json +39 -15
  134. package/types/autocomplete/parts/A11yFocusedOption.d.ts +5 -0
  135. package/types/autocomplete/parts/container/styled.d.ts +1 -1
  136. package/types/autocomplete/parts/styled.d.ts +0 -0
  137. package/types/autocomplete/utils/listHelper.d.ts +5 -5
  138. package/types/checkbox/react-desc-prop-types.d.ts +1 -1
  139. package/types/checkbox/styles.d.ts +1 -0
  140. package/types/combobox/parts/menu-list/styled.d.ts +1 -0
  141. package/types/combobox/react-desc-prop-types.d.ts +8 -6
  142. package/types/combobox/sharedTypes.d.ts +3 -2
  143. package/types/combobox/utils/listHelper.d.ts +1 -0
  144. package/types/date-time-picker/config/useChangeHandlers.d.ts +3 -1
  145. package/types/date-time-picker/config/useControlledDateTimePicker.d.ts +2 -5
  146. package/types/date-time-picker/config/useFocusTracker.d.ts +38 -0
  147. package/types/date-time-picker/config/useGetPropsBasedOnType.d.ts +6 -6
  148. package/types/date-time-picker/config/useGetReferences.d.ts +30 -36
  149. package/types/date-time-picker/config/useGlobalKeyHandlers.d.ts +3 -1
  150. package/types/date-time-picker/parts/DateInputs/DDInput.d.ts +2 -1
  151. package/types/date-time-picker/parts/DateInputs/MMInput.d.ts +2 -1
  152. package/types/date-time-picker/parts/DateInputs/YYYYInput.d.ts +2 -1
  153. package/types/date-time-picker/parts/Pickers/Calendar/useConfigCalendarCTX.d.ts +14 -0
  154. package/types/date-time-picker/parts/Pickers/Calendar/useFocusLogic.d.ts +1 -2
  155. package/types/date-time-picker/parts/Pickers/Calendar/usePopperTriggerLogic.d.ts +19 -0
  156. package/types/date-time-picker/parts/Pickers/TimeWheel/useKeyboardHandlers.d.ts +0 -6
  157. package/types/date-time-picker/parts/Pickers/TimeWheel/usePopperTriggerLogic.d.ts +14 -0
  158. package/types/date-time-picker/parts/TimeInputs/HHInput.d.ts +2 -1
  159. package/types/date-time-picker/parts/TimeInputs/MeridiemInput.d.ts +2 -1
  160. package/types/date-time-picker/parts/TimeInputs/MinutesInput.d.ts +2 -1
  161. package/types/date-time-picker/propTypes.d.ts +117 -0
  162. package/types/date-time-picker/sharedTypes.d.ts +1 -1
  163. package/types/date-time-picker/utils/constants.d.ts +0 -6
  164. package/types/input-group/exported-related/data-test-ids.d.ts +6 -0
  165. package/types/input-group/exported-related/index.d.ts +2 -0
  166. package/types/input-group/exported-related/theming.d.ts +6 -0
  167. package/types/input-group/styled.d.ts +4 -7
  168. package/types/text-input/config/useInputText.d.ts +1 -1
@@ -2,19 +2,21 @@ import _jsx from '@babel/runtime/helpers/esm/jsx';
2
2
  import 'core-js/modules/esnext.async-iterator.filter.js';
3
3
  import 'core-js/modules/esnext.iterator.constructor.js';
4
4
  import 'core-js/modules/esnext.iterator.filter.js';
5
- import React, { useContext, useEffect, useCallback } from 'react';
5
+ import React, { useContext, useEffect, useCallback, useMemo } from 'react';
6
6
  import { DSPopperJS } from '@elliemae/ds-popperjs';
7
7
  import { AutocompleteContext } from '../../AutocompleteCTX.js';
8
- import { StyledContainerWithPopper, StyledPopperWrapper } from './styled.js';
8
+ import { StyledContainer, StyledPopperWrapper } from './styled.js';
9
9
  import { MenuList } from '../menu-list/MenuList.js';
10
10
  import { useKeyboardNavigation } from './useKeyboardNavigation.js';
11
11
  import { AutocompleteDataTestid } from '../../AutocompleteDataTestids.js';
12
- import { jsxs } from 'react/jsx-runtime';
12
+ import { A11yFocusedOption } from '../A11yFocusedOption.js';
13
+ import { jsxs, Fragment } from 'react/jsx-runtime';
13
14
 
14
- var _StyledPopperWrapper;
15
+ var _A11yFocusedOption, _StyledPopperWrapper;
15
16
  const Container = () => {
16
17
  const {
17
18
  props: {
19
+ id,
18
20
  startPlacementPreference,
19
21
  children,
20
22
  filter,
@@ -23,6 +25,7 @@ const Container = () => {
23
25
  showPopover,
24
26
  setReferenceElement,
25
27
  setShowPopover,
28
+ focusOptionIdx,
26
29
  referenceElement
27
30
  } = useContext(AutocompleteContext);
28
31
  useEffect(() => {
@@ -38,32 +41,41 @@ const Container = () => {
38
41
  const handleCloseMenu = useCallback(() => {
39
42
  setShowPopover(false);
40
43
  }, [setShowPopover]);
41
- const input = React.Children.only(children);
42
44
  const {
43
45
  onInputKeyDown
44
46
  } = useKeyboardNavigation();
45
- return /*#__PURE__*/jsxs(StyledContainerWithPopper, {
46
- ref: setReferenceElement,
47
- role: "combobox",
48
- "aria-autocomplete": "list",
49
- "aria-controls": "autocomplete-listbox",
50
- "aria-expanded": showPopover,
51
- onKeyDown: onInputKeyDown,
52
- "data-testid": AutocompleteDataTestid.CONTAINER,
53
- children: [input, filter && /*#__PURE__*/_jsx(DSPopperJS, {
54
- customOffset: [0, 5],
55
- closeContextMenu: handleCloseMenu,
56
- referenceElement: referenceElement,
57
- showPopover: showPopover,
58
- startPlacementPreference: startPlacementPreference,
59
- placementOrderPreference: placementOrderPreference,
60
- withoutPortal: true,
61
- withoutArrow: true,
62
- withoutAnimation: true,
63
- zIndex: 10
64
- }, void 0, _StyledPopperWrapper || (_StyledPopperWrapper = /*#__PURE__*/_jsx(StyledPopperWrapper, {
65
- tabIndex: -1
66
- }, void 0, /*#__PURE__*/_jsx(MenuList, {}))))]
47
+ const input = React.Children.only(children);
48
+ const childrenWithProps = /*#__PURE__*/React.isValidElement(input) ? /*#__PURE__*/React.cloneElement(input, {
49
+ 'aria-activedescendant': focusOptionIdx
50
+ }) : input;
51
+ const idList = useMemo(() => "".concat(id ? "".concat(id, "-") : '', "listbox"), [id]);
52
+ return /*#__PURE__*/jsxs(Fragment, {
53
+ children: [_A11yFocusedOption || (_A11yFocusedOption = /*#__PURE__*/_jsx(A11yFocusedOption, {})), /*#__PURE__*/jsxs(StyledContainer, {
54
+ id: id,
55
+ ref: setReferenceElement,
56
+ role: "combobox",
57
+ "aria-autocomplete": "list",
58
+ "aria-controls": "autocomplete-listbox",
59
+ "aria-expanded": showPopover,
60
+ "aria-haspopup": "listbox",
61
+ "aria-owns": idList,
62
+ onKeyDown: onInputKeyDown,
63
+ "data-testid": AutocompleteDataTestid.CONTAINER,
64
+ children: [childrenWithProps, filter && /*#__PURE__*/_jsx(DSPopperJS, {
65
+ customOffset: [0, 5],
66
+ closeContextMenu: handleCloseMenu,
67
+ referenceElement: referenceElement,
68
+ showPopover: showPopover,
69
+ startPlacementPreference: startPlacementPreference,
70
+ placementOrderPreference: placementOrderPreference,
71
+ withoutPortal: true,
72
+ withoutArrow: true,
73
+ withoutAnimation: true,
74
+ zIndex: 10
75
+ }, void 0, _StyledPopperWrapper || (_StyledPopperWrapper = /*#__PURE__*/_jsx(StyledPopperWrapper, {
76
+ tabIndex: -1
77
+ }, void 0, /*#__PURE__*/_jsx(MenuList, {}))))]
78
+ })]
67
79
  });
68
80
  };
69
81
 
@@ -1,10 +1,10 @@
1
1
  import styled from 'styled-components';
2
2
 
3
- const StyledContainerWithPopper = /*#__PURE__*/styled.div.withConfig({
3
+ const StyledContainer = /*#__PURE__*/styled.div.withConfig({
4
4
  componentId: "sc-xupfk9-0"
5
5
  })(["width:100%;height:28px;position:relative;"]);
6
6
  const StyledPopperWrapper = /*#__PURE__*/styled.div.withConfig({
7
7
  componentId: "sc-xupfk9-1"
8
8
  })(["background:#fff;overflow:auto;position:relative;"]);
9
9
 
10
- export { StyledContainerWithPopper, StyledPopperWrapper };
10
+ export { StyledContainer, StyledPopperWrapper };
@@ -1,5 +1,5 @@
1
1
  import _jsx from '@babel/runtime/helpers/esm/jsx';
2
- import { useContext, useCallback } from 'react';
2
+ import { useContext, useCallback, useMemo } from 'react';
3
3
  import { StyledListWrapper, StyledVirtualListWrapper, StyledList } from './styled.js';
4
4
  import { AutocompleteDataTestid } from '../../AutocompleteDataTestids.js';
5
5
  import { AutocompleteContext } from '../../AutocompleteCTX.js';
@@ -9,7 +9,8 @@ import { jsx } from 'react/jsx-runtime';
9
9
  const MenuList = () => {
10
10
  const {
11
11
  props: {
12
- options
12
+ options,
13
+ id
13
14
  },
14
15
  referenceElement,
15
16
  inputRef,
@@ -25,11 +26,12 @@ const MenuList = () => {
25
26
 
26
27
  (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
27
28
  }, [inputRef]);
29
+ const idList = useMemo(() => "".concat(id ? "".concat(id, "-") : '', "listbox"), [id]);
28
30
  return /*#__PURE__*/_jsx(StyledListWrapper, {
29
31
  tabIndex: -1,
30
32
  onMouseDown: e => e.preventDefault(),
31
33
  minWidth: referenceElement === null || referenceElement === void 0 ? void 0 : referenceElement.offsetWidth,
32
- id: "autocomplete-listbox",
34
+ id: idList,
33
35
  role: "listbox"
34
36
  }, void 0, options.length > 0 && /*#__PURE__*/jsx(StyledVirtualListWrapper, {
35
37
  tabIndex: -1,
@@ -0,0 +1 @@
1
+
@@ -9,7 +9,7 @@ const isSelectedValueMultiple = value => Array.isArray(value);
9
9
  const findInCircularList = function (list, from, criteria) {
10
10
  let step = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
11
11
 
12
- for (let i = (from + step + list.length) % list.length; i !== from; i = (i + step + list.length) % list.length) {
12
+ for (let i = (from + step + list.length) % list.length; i !== from && from > -1; i = (i + step + list.length) % list.length) {
13
13
  if (criteria(list[i])) return i;
14
14
  }
15
15
 
@@ -9,7 +9,7 @@ import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutPr
9
9
  import { useRef, useCallback } from 'react';
10
10
  import { describe, useMemoMergePropsWithDefault, useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';
11
11
  import { SimpleTruncatedTooltipText } from '@elliemae/ds-truncated-tooltip-text';
12
- import { StyledContainer, StyledCheckBox, StyledInputMixed, StyledInput, StyledLabel } from './styles.js';
12
+ import { StyledContainer, StyledCheckBox, StyledInputMixed, StyledInput, StyledLabel, StyledWrapLabel } from './styles.js';
13
13
  import { propTypes, defaultProps } from './react-desc-prop-types.js';
14
14
  import { setMultipleRefs } from './utils/setMultipleRefs.js';
15
15
  import { useValidateProps } from './config/useValidateProps.js';
@@ -98,7 +98,7 @@ const DSControlledCheckbox = props => {
98
98
  checked: checked,
99
99
  "data-testid": "ds-checkbox-label",
100
100
  wrapLabel: wrapLabel
101
- }, void 0, wrapLabel ? label : /*#__PURE__*/_jsx(SimpleTruncatedTooltipText, {
101
+ }, void 0, wrapLabel ? /*#__PURE__*/_jsx(StyledWrapLabel, {}, void 0, label) : /*#__PURE__*/_jsx(SimpleTruncatedTooltipText, {
102
102
  value: label
103
103
  }))]
104
104
  }));
@@ -18,7 +18,8 @@ const defaultProps = {
18
18
  const propTypes = _objectSpread(_objectSpread({}, globalAttributesPropTypes), {}, {
19
19
  label: PropTypes.string.description('Checkbox Label property. This label is also going to be used as an aria-label for screen readers.'),
20
20
  hasError: PropTypes.bool.description('Whether the checkbox has error or not.'),
21
- innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).description('Checkbox input ref.')
21
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).description('Checkbox input ref.'),
22
+ wrapLabel: PropTypes.bool.description('Whether to wrap or truncate the label')
22
23
  });
23
24
 
24
25
  export { defaultProps, propTypes };
@@ -3,7 +3,7 @@ import { styled, css } from '@elliemae/ds-system';
3
3
  import { handleBackgroundColor, handleCheckmark } from './utils/styleHelpers.js';
4
4
  import { DSCheckboxName, DSCheckboxSlots } from './exported-related/theming.js';
5
5
 
6
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6;
6
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
7
7
  const StyledContainer = styled('div', {
8
8
  name: DSCheckboxName,
9
9
  slot: DSCheckboxSlots.CONTAINER
@@ -93,7 +93,7 @@ const StyledLabel = styled('label', {
93
93
  wrapLabel,
94
94
  theme
95
95
  } = _ref11;
96
- return wrapLabel ? 'padding: 8px' : "padding-left: ".concat(theme.space.xxs);
96
+ return wrapLabel ? 'padding: 8px 0px 8px 8px;' : "padding-left: ".concat(theme.space.xxs);
97
97
  }, _ref12 => {
98
98
  let {
99
99
  theme,
@@ -103,5 +103,6 @@ const StyledLabel = styled('label', {
103
103
  } = _ref12;
104
104
  return disabled && checked !== true || readOnly ? theme.colors.neutral[500] : theme.colors.neutral[800];
105
105
  });
106
+ const StyledWrapLabel = styled('span')(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral([""])));
106
107
 
107
- export { StyledCheckBox, StyledContainer, StyledInput, StyledInputMixed, StyledLabel };
108
+ export { StyledCheckBox, StyledContainer, StyledInput, StyledInputMixed, StyledLabel, StyledWrapLabel };
@@ -12,12 +12,14 @@ const defaultProps = {
12
12
  useMask: noop,
13
13
  innerRef: /*#__PURE__*/createRef(),
14
14
  startPlacementPreference: 'bottom-start',
15
- placementOrderPreference: ['bottom-start', 'bottom-end'] // override in useCombobox to avoid ref duplications when more than one cb is used
15
+ placementOrderPreference: ['bottom-start', 'bottom-end'],
16
+ noOptionsMessage: 'No Matches Found',
17
+ filteredOptions: [] // override in useCombobox to avoid ref duplications when more than one cb is used
16
18
 
17
19
  };
18
20
  const defaultContext = {
19
21
  props: defaultProps,
20
- showPopover: false,
22
+ menuState: false,
21
23
  hasFocus: false,
22
24
  referenceElement: null,
23
25
  inputValue: '',
@@ -36,7 +38,8 @@ const defaultContext = {
36
38
  setInputValue: noop,
37
39
  setReferenceElement: noop,
38
40
  setFocusOptionIdx: noop,
39
- setShowSelectedOptions: noop
41
+ setShowSelectedOptions: noop,
42
+ setMenuState: noop
40
43
  };
41
44
  /** Context for cross component communication */
42
45
 
@@ -5,7 +5,7 @@ import 'core-js/modules/esnext.async-iterator.for-each.js';
5
5
  import 'core-js/modules/esnext.iterator.for-each.js';
6
6
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
7
7
  import 'core-js/modules/web.dom-collections.iterator.js';
8
- import { useRef, useState, useCallback, useEffect, useMemo } from 'react';
8
+ import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
9
9
  import { useVirtual } from 'react-virtual';
10
10
  import { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';
11
11
  import { defaultProps } from '../ComboBoxCTX.js';
@@ -36,8 +36,18 @@ const useComboBox = props => {
36
36
  const toggleSelectionButtonRef = useRef(null);
37
37
  const pillGroupRef = useRef(null);
38
38
  const {
39
- selectedValues
40
- } = propsWithDefaults; // ---------------------------------------------------------------------------
39
+ selectedValues,
40
+ isMenuOpen,
41
+ onMenuChange
42
+ } = propsWithDefaults;
43
+ const menuState = useMemo(() => {
44
+ if (isMenuOpen !== undefined) return isMenuOpen;
45
+ return showPopover;
46
+ }, [showPopover, isMenuOpen]);
47
+ const setMenuState = useCallback((newState, reason, e) => {
48
+ if (onMenuChange !== undefined) onMenuChange(newState, reason, e);
49
+ setShowPopover(newState);
50
+ }, [onMenuChange]); // ---------------------------------------------------------------------------
41
51
  // Options with creatable option + filtered by selected
42
52
  // ---------------------------------------------------------------------------
43
53
 
@@ -91,7 +101,7 @@ const useComboBox = props => {
91
101
  filteredOptions: correctOptions
92
102
  }),
93
103
  virtualListHelpers,
94
- showPopover,
104
+ menuState,
95
105
  referenceElement,
96
106
  listRef,
97
107
  focusOptionIdx,
@@ -100,6 +110,7 @@ const useComboBox = props => {
100
110
  selectAllCheckboxRef,
101
111
  inputValue,
102
112
  setInputValue,
113
+ setMenuState,
103
114
  hasFocus,
104
115
  toggleSelectionButtonRef,
105
116
  pillGroupRef,
@@ -111,7 +122,7 @@ const useComboBox = props => {
111
122
  scrollOptionIntoView,
112
123
  setReferenceElement,
113
124
  setShowPopover
114
- }), [scrollOptionIntoView, correctOptions, hasFocus, propsWithDefaults, virtualListHelpers, inputValue, focusOptionIdx, wrapperListRef, showSelectedOptions, showPopover, pillGroupRef, referenceElement, selectedOptionsRef, controlsWrapperRef, selectAllCheckboxRef, toggleSelectionButtonRef, listRef]);
125
+ }), [scrollOptionIntoView, setMenuState, correctOptions, hasFocus, propsWithDefaults, virtualListHelpers, inputValue, focusOptionIdx, wrapperListRef, showSelectedOptions, menuState, pillGroupRef, referenceElement, selectedOptionsRef, controlsWrapperRef, selectAllCheckboxRef, toggleSelectionButtonRef, listRef]);
115
126
  return ctx;
116
127
  };
117
128
 
@@ -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
  }
@@ -20,7 +20,7 @@ const DropdownIndicator = () => {
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",
@@ -28,15 +28,13 @@ 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,
@@ -52,20 +50,19 @@ 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]);
65
+ }, [setMenuState]);
69
66
  return useMemo(() => /*#__PURE__*/jsx(StyledContainer, _objectSpread(_objectSpread(_objectSpread({
70
67
  "data-testid": ComboboxDataTestid.CONTAINER,
71
68
  ref: setReferenceElement
@@ -76,7 +73,7 @@ const Container = () => {
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, setReferenceElement, globalsAttrs, referenceElement, showPopover, xStyledProps, 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 };
@@ -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,12 +25,12 @@ const Controls = () => {
24
25
  innerRef
25
26
  },
26
27
  selectedOptionsRef,
27
- setShowPopover,
28
+ setMenuState,
28
29
  setFocusOptionIdx,
29
30
  hasFocus,
30
31
  listRef,
31
32
  focusOptionIdx,
32
- showPopover,
33
+ menuState,
33
34
  controlsWrapperRef
34
35
  } = useContext(ComboBoxContext);
35
36
  const handleOnClick = useCallback(() => {
@@ -37,37 +38,34 @@ const Controls = () => {
37
38
 
38
39
  if (disabled) return;
39
40
 
40
- if (hasFocus && showPopover && !inline) {
41
+ if (hasFocus && menuState && !inline) {
41
42
  var _innerRef$current;
42
43
 
43
- setShowPopover(false);
44
+ setMenuState(false);
44
45
  setFocusOptionIdx('');
45
46
  (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.blur();
46
47
  return;
47
48
  }
48
49
 
49
50
  (_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 ? void 0 : _innerRef$current2.focus();
50
- setShowPopover(true);
51
+ setMenuState(true);
51
52
  window.requestAnimationFrame(() => {
52
- if (listRef.current && window.scrollY < listRef.current.scrollHeight) {
53
- window.scrollTo({
54
- top: listRef.current.scrollHeight,
55
- behavior: 'smooth'
56
- });
57
- }
53
+ window.requestAnimationFrame(() => {
54
+ if (listRef.current) scrollIfNeeded(listRef.current);
55
+ });
58
56
  }); // eslint-disable-next-line react-hooks/exhaustive-deps
59
- }, [disabled, listRef, hasFocus, showPopover, inline, innerRef, setShowPopover, focusOptionIdx]); // this callback prevent to toggle the menu when clicking or removing pills
57
+ }, [disabled, listRef, hasFocus, menuState, inline, innerRef, setMenuState, focusOptionIdx]); // this callback prevent to toggle the menu when clicking or removing pills
60
58
 
61
59
  const handleOnPillsClick = useCallback(e => {
62
- if (showPopover || disabled) {
60
+ if (menuState || disabled) {
63
61
  e.stopPropagation();
64
62
  } else {
65
63
  var _innerRef$current3;
66
64
 
67
65
  (_innerRef$current3 = innerRef.current) === null || _innerRef$current3 === void 0 ? void 0 : _innerRef$current3.focus();
68
- setShowPopover(true);
66
+ setMenuState(true);
69
67
  }
70
- }, [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
71
69
 
72
70
  const handleOnMouseDown = useCallback(e => {
73
71
  if (document.activeElement === innerRef.current || inline) {
@@ -92,12 +90,12 @@ const Controls = () => {
92
90
  children: [!inline && /*#__PURE__*/jsxs(StyledSelection, {
93
91
  ref: selectedOptionsRef,
94
92
  onClick: handleOnPillsClick,
95
- 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", {
96
94
  "data-testid": ComboboxDataTestid.SELECTED_VALUES
97
95
  }, void 0, selectedValues && /*#__PURE__*/_jsx(RemovableSelectedValuePill, {
98
96
  pill: selectedValues
99
97
  }))]
100
- }), _ControlsInput || (_ControlsInput = /*#__PURE__*/_jsx(ControlsInput, {})), !inline && /*#__PURE__*/_jsx(StyledHeaderActionsWrapper, {
98
+ }), _A11yFocusedOption || (_A11yFocusedOption = /*#__PURE__*/_jsx(A11yFocusedOption, {})), _ControlsInput || (_ControlsInput = /*#__PURE__*/_jsx(ControlsInput, {})), !inline && /*#__PURE__*/_jsx(StyledHeaderActionsWrapper, {
101
99
  justifyContent: "center",
102
100
  cols: ['min-content', 'min-content']
103
101
  }, void 0, /*#__PURE__*/_jsx(StyleHeaderActionsSeparator, {
@@ -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,7 +44,7 @@ const ControlsInput = () => {
44
44
  placeholder: placeholder,
45
45
  "aria-controls": "combo-listbox",
46
46
  "aria-activedescendant": focusOptionIdx,
47
- "aria-expanded": showPopover,
47
+ "aria-expanded": menuState,
48
48
  "aria-haspopup": "listbox",
49
49
  "aria-describedby": "combobox-selected-items",
50
50
  role: "combobox",
@@ -15,6 +15,7 @@ const useControlsInput = () => {
15
15
  },
16
16
  setHasFocus,
17
17
  inputValue,
18
+ setMenuState,
18
19
  setInputValue
19
20
  } = useContext(ComboBoxContext);
20
21
  const [width, setWidth] = useState(1); // use span reference to calculate the real width for the input
@@ -32,9 +33,9 @@ const useControlsInput = () => {
32
33
  const handleOnChange = useMaskedOnChange();
33
34
  const handleOnBlur = useCallback(() => {
34
35
  setInputValue('');
35
- if (onFilter) onFilter(allOptions, inputValue);
36
+ if (onFilter) onFilter(allOptions);
36
37
  setHasFocus(false);
37
- }, [setInputValue, onFilter, allOptions, inputValue, setHasFocus]);
38
+ }, [setInputValue, onFilter, allOptions, setHasFocus]);
38
39
  const handleOnFocus = useCallback(() => {
39
40
  setHasFocus(true);
40
41
  }, [setHasFocus]);