@elliemae/ds-controlled-form 2.4.2-rc.0 → 2.4.2-rc.1
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.
- package/cjs/autocomplete/config/useAutocomplete.js +1 -3
- package/cjs/checkbox/ControlledCheckbox.js +49 -33
- package/cjs/checkbox/exported-related/data-test-ids.js +10 -0
- package/cjs/checkbox/exported-related/index.js +12 -0
- package/cjs/checkbox/exported-related/theming.js +13 -0
- package/cjs/checkbox/react-desc-prop-types.js +0 -1
- package/cjs/checkbox/styles.js +26 -15
- package/cjs/combobox/ComboBoxCTX.js +1 -1
- package/cjs/combobox/ComboboxDataTestids.js +1 -1
- package/cjs/combobox/config/useComboBox.js +6 -4
- package/cjs/combobox/index.js +5 -0
- package/cjs/combobox/parts/DropdownIndicator.js +2 -2
- package/cjs/combobox/parts/container/Container.js +5 -5
- package/cjs/combobox/parts/container/styled.js +13 -7
- package/cjs/combobox/parts/controls/Controls.js +14 -4
- package/cjs/combobox/parts/controls/styled.js +22 -13
- package/cjs/combobox/parts/controls-input/ControlsInput.js +1 -1
- package/cjs/combobox/parts/controls-input/styled.js +7 -3
- package/cjs/combobox/parts/controls-input/useControlsInput.js +3 -4
- package/cjs/combobox/parts/controls-input/useKeyboardNavigation.js +30 -15
- package/cjs/combobox/parts/header-list/HeaderList.js +4 -3
- package/cjs/combobox/parts/header-list/useHeaderListHandlers.js +9 -5
- package/cjs/combobox/parts/menu-list/MenuList.js +5 -2
- package/cjs/combobox/parts/menu-list/styled.js +12 -7
- package/cjs/combobox/parts/menu-list/useItemRenderer.js +5 -4
- package/cjs/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +1 -1
- package/cjs/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +2 -0
- package/cjs/combobox/parts/multi-selected-values-container/useGroupPills.js +13 -10
- package/cjs/combobox/theming.js +13 -0
- package/cjs/combobox/utils/listHelper.js +2 -1
- package/cjs/index.js +16 -7
- package/cjs/input-group/InputGroup.js +69 -0
- package/cjs/input-group/InputGroupDataTestIds.js +12 -0
- package/cjs/input-group/index.js +12 -0
- package/cjs/input-group/react-desc-prop-types.js +14 -0
- package/cjs/input-group/styled.js +46 -0
- package/cjs/mask-hook/hooks/index.js +0 -1
- package/cjs/mask-hook/hooks/usePhoneMask.js +2 -2
- package/cjs/mask-hook/hooks/useRegExpMask.js +0 -1
- package/cjs/mask-hook/index.js +0 -1
- package/cjs/text-input/styled/borders.js +1 -1
- package/esm/autocomplete/config/useAutocomplete.js +1 -3
- package/esm/checkbox/ControlledCheckbox.js +52 -36
- package/esm/checkbox/exported-related/data-test-ids.js +6 -0
- package/esm/checkbox/exported-related/index.js +2 -0
- package/esm/checkbox/exported-related/theming.js +8 -0
- package/esm/checkbox/react-desc-prop-types.js +0 -1
- package/esm/checkbox/styles.js +25 -15
- package/esm/combobox/ComboBoxCTX.js +1 -1
- package/esm/combobox/ComboboxDataTestids.js +1 -1
- package/esm/combobox/config/useComboBox.js +6 -4
- package/esm/combobox/index.js +2 -0
- package/esm/combobox/parts/DropdownIndicator.js +2 -2
- package/esm/combobox/parts/container/Container.js +7 -7
- package/esm/combobox/parts/container/styled.js +13 -6
- package/esm/combobox/parts/controls/Controls.js +14 -4
- package/esm/combobox/parts/controls/styled.js +22 -13
- package/esm/combobox/parts/controls-input/ControlsInput.js +1 -1
- package/esm/combobox/parts/controls-input/styled.js +7 -3
- package/esm/combobox/parts/controls-input/useControlsInput.js +3 -4
- package/esm/combobox/parts/controls-input/useKeyboardNavigation.js +30 -15
- package/esm/combobox/parts/header-list/HeaderList.js +4 -3
- package/esm/combobox/parts/header-list/useHeaderListHandlers.js +9 -5
- package/esm/combobox/parts/menu-list/MenuList.js +5 -2
- package/esm/combobox/parts/menu-list/styled.js +12 -7
- package/esm/combobox/parts/menu-list/useItemRenderer.js +5 -4
- package/esm/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +1 -1
- package/esm/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +2 -0
- package/esm/combobox/parts/multi-selected-values-container/useGroupPills.js +13 -10
- package/esm/combobox/theming.js +8 -0
- package/esm/combobox/utils/listHelper.js +2 -1
- package/esm/index.js +5 -1
- package/esm/input-group/InputGroup.js +59 -0
- package/esm/input-group/InputGroupDataTestIds.js +8 -0
- package/esm/input-group/index.js +2 -0
- package/esm/input-group/react-desc-prop-types.js +10 -0
- package/esm/input-group/styled.js +35 -0
- package/esm/mask-hook/hooks/index.js +1 -1
- package/esm/mask-hook/hooks/usePhoneMask.js +2 -2
- package/esm/mask-hook/hooks/useRegExpMask.js +1 -1
- package/esm/mask-hook/index.js +1 -1
- package/esm/text-input/styled/borders.js +1 -1
- package/package.json +51 -19
- package/types/checkbox/exported-related/data-test-ids.d.ts +4 -0
- package/types/checkbox/exported-related/index.d.ts +2 -0
- package/types/checkbox/exported-related/theming.d.ts +6 -0
- package/types/checkbox/react-desc-prop-types.d.ts +3 -3
- package/types/checkbox/styles.d.ts +5 -5
- package/types/combobox/ComboboxDataTestids.d.ts +1 -1
- package/types/combobox/index.d.ts +2 -0
- package/types/combobox/parts/container/styled.d.ts +1 -2
- package/types/combobox/theming.d.ts +6 -0
- package/types/index.d.ts +1 -0
- package/types/input-group/InputGroup.d.ts +5 -0
- package/types/input-group/InputGroupDataTestIds.d.ts +6 -0
- package/types/input-group/index.d.ts +2 -0
- package/types/input-group/react-desc-prop-types.d.ts +19 -0
- package/types/input-group/styled.d.ts +7 -0
- package/types/input-group/tests/DSInputGroup.test.d.ts +1 -0
- package/types/mask-hook/hooks/useRegExpMask.d.ts +0 -1
- package/types/text-input/config/useInputText.d.ts +5 -5
- package/cjs/combobox/parts/menu-list/useMenuListSetFocusOption.js +0 -51
- package/esm/combobox/parts/menu-list/useMenuListSetFocusOption.js +0 -47
- package/types/combobox/parts/menu-list/useMenuListSetFocusOption.d.ts +0 -1
|
@@ -28,6 +28,7 @@ const useKeyboardNavigation = () => {
|
|
|
28
28
|
inputValue,
|
|
29
29
|
showPopover,
|
|
30
30
|
focusOptionIdx,
|
|
31
|
+
listRef,
|
|
31
32
|
selectAllCheckboxRef,
|
|
32
33
|
toggleSelectionButtonRef,
|
|
33
34
|
setShowPopover,
|
|
@@ -47,6 +48,14 @@ const useKeyboardNavigation = () => {
|
|
|
47
48
|
|
|
48
49
|
if (['ArrowDown', 'ArrowUp', 'Enter', 'Spacebar'].includes(e.key) || e.keyCode >= 48 && e.keyCode <= 90) {
|
|
49
50
|
setShowPopover(true);
|
|
51
|
+
window.requestAnimationFrame(() => {
|
|
52
|
+
if (listRef.current && window.scrollY < listRef.current.offsetHeight) {
|
|
53
|
+
window.scrollTo({
|
|
54
|
+
top: listRef.current.offsetHeight,
|
|
55
|
+
behavior: 'smooth'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
50
59
|
} // =============================================================================
|
|
51
60
|
// ESCAPE
|
|
52
61
|
// =============================================================================
|
|
@@ -67,7 +76,7 @@ const useKeyboardNavigation = () => {
|
|
|
67
76
|
|
|
68
77
|
|
|
69
78
|
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
|
|
79
|
+
onCreate(inputValue); // blank active item to force search last one
|
|
71
80
|
|
|
72
81
|
setFocusOptionIdx('');
|
|
73
82
|
if (onFilter) onFilter(allOptions, '');
|
|
@@ -110,9 +119,12 @@ const useKeyboardNavigation = () => {
|
|
|
110
119
|
e.stopPropagation();
|
|
111
120
|
|
|
112
121
|
if ((showPopover || inline) && selectableOptions.length) {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
const nextItemIndexIndex = findInCircularList(filteredOptions, currentItemIndex, isOptionFocuseable);
|
|
123
|
+
|
|
124
|
+
if (nextItemIndexIndex > -1) {
|
|
125
|
+
setFocusOptionIdx(filteredOptions[nextItemIndexIndex].dsId);
|
|
126
|
+
scrollOptionIntoView(filteredOptions[nextItemIndexIndex].dsId);
|
|
127
|
+
}
|
|
116
128
|
}
|
|
117
129
|
}
|
|
118
130
|
|
|
@@ -122,16 +134,19 @@ const useKeyboardNavigation = () => {
|
|
|
122
134
|
if (!selectableOptions.length) return;
|
|
123
135
|
const prevItemIndex = findInCircularList(filteredOptions, currentItemIndex, isOptionFocuseable, -1);
|
|
124
136
|
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
if (prevItemIndex > -1) {
|
|
138
|
+
if (showPopover || inline) {
|
|
139
|
+
setFocusOptionIdx(filteredOptions[prevItemIndex].dsId);
|
|
140
|
+
scrollOptionIntoView(filteredOptions[prevItemIndex].dsId);
|
|
141
|
+
} else {
|
|
142
|
+
// open menu and search last item to focused
|
|
143
|
+
setShowPopover(true);
|
|
144
|
+
const lastItemIndex = findInCircularList(filteredOptions, 0, isOptionFocuseable, -1);
|
|
145
|
+
setFocusOptionIdx(filteredOptions[lastItemIndex].dsId);
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
scrollOptionIntoView(filteredOptions[lastItemIndex].dsId);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
135
150
|
}
|
|
136
151
|
} // =============================================================================
|
|
137
152
|
// BACKSPACE
|
|
@@ -163,7 +178,7 @@ const useKeyboardNavigation = () => {
|
|
|
163
178
|
setShowPopover(false);
|
|
164
179
|
}
|
|
165
180
|
}, // 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]);
|
|
181
|
+
[onKeyDown, currentItem, onCreate, multiple, inputValue, inline, withoutPortal, setShowPopover, onCancel, onFilter, setInputValue, listRef, focusOptionIdx, showPopover, selectableOptions.length, filteredOptions, currentItemIndex, setFocusOptionIdx, selectedValues, onChange, selectAllCheckboxRef, toggleSelectionButtonRef]);
|
|
167
182
|
return {
|
|
168
183
|
onInputKeyDown
|
|
169
184
|
};
|
|
@@ -14,6 +14,7 @@ const HeaderList = () => {
|
|
|
14
14
|
const {
|
|
15
15
|
props: {
|
|
16
16
|
selectedValues,
|
|
17
|
+
filteredOptions,
|
|
17
18
|
onSelectAll
|
|
18
19
|
},
|
|
19
20
|
showSelectedOptions,
|
|
@@ -32,15 +33,15 @@ const HeaderList = () => {
|
|
|
32
33
|
} = useHeaderListHandlers();
|
|
33
34
|
return /*#__PURE__*/_jsx(StyledHeaderListWrapper, {
|
|
34
35
|
onKeyDown: handleKeyDown,
|
|
35
|
-
onMouseDown: handleOnMouseDown
|
|
36
|
+
onMouseDown: handleOnMouseDown,
|
|
37
|
+
"data-testid": ComboboxDataTestid.MULTISELECT.HEADER_LIST
|
|
36
38
|
}, void 0, /*#__PURE__*/_jsx(StyledSelectAllCheckbox, {}, void 0, onSelectAll && /*#__PURE__*/_jsx(DSControlledCheckbox, {
|
|
37
39
|
checked: checkboxStatus,
|
|
38
|
-
"aria-controls":
|
|
40
|
+
"aria-controls": filteredOptions.map(item => item.dsId).join(' '),
|
|
39
41
|
name: "select-all-checkbox",
|
|
40
42
|
"aria-label": "Select/Unselect All Items",
|
|
41
43
|
id: "select-all-checkbox",
|
|
42
44
|
onChange: handleSelectAllCheckboxChange,
|
|
43
|
-
"data-testid": ComboboxDataTestid.MULTISELECT.SELECT_ALL_CHECKBOX,
|
|
44
45
|
onKeyDown: handleCheckAllOnTab,
|
|
45
46
|
innerRef: selectAllCheckboxRef
|
|
46
47
|
})), /*#__PURE__*/_jsx(StyledSelectedItems, {}, void 0, multiSelectedValues.length > 0 ? /*#__PURE__*/_jsx(StyledButtonSelection, {
|
|
@@ -51,27 +51,31 @@ const useHeaderListHandlers = () => {
|
|
|
51
51
|
e.preventDefault();
|
|
52
52
|
setShowSelectedOptions(!showSelectedOptions);
|
|
53
53
|
}, [setShowSelectedOptions, showSelectedOptions]); // when pressing escape on each header list button we close the menu
|
|
54
|
+
// and set focus on input
|
|
54
55
|
|
|
55
56
|
const handleKeyDown = useCallback(e => {
|
|
56
57
|
if (e.key === 'Escape') {
|
|
58
|
+
var _innerRef$current;
|
|
59
|
+
|
|
57
60
|
setShowPopover(false);
|
|
61
|
+
(_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.focus();
|
|
58
62
|
}
|
|
59
|
-
}, [setShowPopover]); // when hitting tab on selected values button filter we target the input again
|
|
63
|
+
}, [setShowPopover, innerRef]); // when hitting tab on selected values button filter we target the input again
|
|
60
64
|
|
|
61
65
|
const handleFilterSelectionBtnOnTab = useCallback(e => {
|
|
62
66
|
if (e.key === 'Tab' && !e.shiftKey) {
|
|
63
|
-
var _innerRef$
|
|
67
|
+
var _innerRef$current2;
|
|
64
68
|
|
|
65
69
|
e.preventDefault();
|
|
66
|
-
(_innerRef$
|
|
70
|
+
(_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 ? void 0 : _innerRef$current2.focus();
|
|
67
71
|
}
|
|
68
72
|
}, [innerRef]);
|
|
69
73
|
const handleCheckAllOnTab = useCallback(e => {
|
|
70
74
|
if (e.key === 'Tab' && !e.shiftKey && multiSelectedValues.length === 0) {
|
|
71
|
-
var _innerRef$
|
|
75
|
+
var _innerRef$current3;
|
|
72
76
|
|
|
73
77
|
e.preventDefault();
|
|
74
|
-
(_innerRef$
|
|
78
|
+
(_innerRef$current3 = innerRef.current) === null || _innerRef$current3 === void 0 ? void 0 : _innerRef$current3.focus();
|
|
75
79
|
}
|
|
76
80
|
}, [innerRef, multiSelectedValues]);
|
|
77
81
|
useEffect(() => {
|
|
@@ -40,7 +40,9 @@ const MenuList = () => {
|
|
|
40
40
|
inline: inline,
|
|
41
41
|
onMouseDown: preventLoseInputFocus,
|
|
42
42
|
width: width,
|
|
43
|
-
minWidth: menuMinWidth
|
|
43
|
+
minWidth: menuMinWidth // we use width as key to force react virtual re-render on window resize
|
|
44
|
+
// and update the item height accordly
|
|
45
|
+
,
|
|
44
46
|
children: [withHeader && (_HeaderList || (_HeaderList = /*#__PURE__*/_jsx(HeaderList, {}))), filteredOptions.length > 0 || onCreate ? /*#__PURE__*/jsx(StyledVirtualListWrapper, {
|
|
45
47
|
inline: inline,
|
|
46
48
|
maxHeight: menuMaxHeight,
|
|
@@ -56,9 +58,10 @@ const MenuList = () => {
|
|
|
56
58
|
}
|
|
57
59
|
}, void 0, ItemRenderer)
|
|
58
60
|
}) : _StyledNoResultsWrapp || (_StyledNoResultsWrapp = /*#__PURE__*/_jsx(StyledNoResultsWrapper, {
|
|
61
|
+
role: "alert",
|
|
59
62
|
"aria-live": "polite"
|
|
60
63
|
}, void 0, "No matches found"))]
|
|
61
|
-
}), [wrapperListRef, inline, preventLoseInputFocus,
|
|
64
|
+
}, width), [wrapperListRef, inline, preventLoseInputFocus, menuMinWidth, withHeader, filteredOptions.length, onCreate, menuMaxHeight, listRef, virtualListHelpers === null || virtualListHelpers === void 0 ? void 0 : virtualListHelpers.totalSize, ItemRenderer, width]);
|
|
62
65
|
};
|
|
63
66
|
|
|
64
67
|
export { MenuList };
|
|
@@ -2,7 +2,7 @@ import _taggedTemplateLiteral from '@babel/runtime/helpers/esm/taggedTemplateLit
|
|
|
2
2
|
import { styled } from '@elliemae/ds-system';
|
|
3
3
|
|
|
4
4
|
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
|
|
5
|
-
const StyledListWrapper = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n min-width: ", ";\n width: ", ";\n background-color: #ffffff;\n"])), _ref => {
|
|
5
|
+
const StyledListWrapper = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n min-width: ", ";\n width: ", ";\n background-color: #ffffff;\n max-height: ", ";\n z-index: 100;\n"])), _ref => {
|
|
6
6
|
let {
|
|
7
7
|
inline,
|
|
8
8
|
minWidth
|
|
@@ -13,18 +13,23 @@ const StyledListWrapper = styled.div(_templateObject || (_templateObject = _tagg
|
|
|
13
13
|
width
|
|
14
14
|
} = _ref2;
|
|
15
15
|
return "".concat(width, "px");
|
|
16
|
+
}, _ref3 => {
|
|
17
|
+
let {
|
|
18
|
+
maxHeight
|
|
19
|
+
} = _ref3;
|
|
20
|
+
return "".concat(maxHeight, "px");
|
|
16
21
|
});
|
|
17
|
-
const StyledList = styled.ul(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n padding: 0;\n"])));
|
|
18
|
-
const StyledVirtualListWrapper = styled.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n overflow-y: auto;\n margin-top: ", ";\n
|
|
22
|
+
const StyledList = styled.ul(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n padding: 0;\n background-color: #ffffff;\n"])));
|
|
23
|
+
const StyledVirtualListWrapper = styled.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n overflow-y: auto;\n margin-top: ", ";\n max-height: ", ";\n"])), _ref4 => {
|
|
19
24
|
let {
|
|
20
25
|
withHeader
|
|
21
|
-
} =
|
|
26
|
+
} = _ref4;
|
|
22
27
|
return withHeader ? '28px' : '';
|
|
23
|
-
},
|
|
28
|
+
}, _ref5 => {
|
|
24
29
|
let {
|
|
25
30
|
maxHeight
|
|
26
|
-
} =
|
|
27
|
-
return
|
|
31
|
+
} = _ref5;
|
|
32
|
+
return maxHeight ? "".concat(maxHeight, "px") : '300px';
|
|
28
33
|
});
|
|
29
34
|
const StyledCreatableLabel = styled.span(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n font-weight: bold;\n font-style: italic;\n"])));
|
|
30
35
|
const StyledNoResultsWrapper = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n padding: 16px;\n"])));
|
|
@@ -78,9 +78,10 @@ const useItemRenderer = () => {
|
|
|
78
78
|
const generalProps = {
|
|
79
79
|
wrapperStyles: {
|
|
80
80
|
position: 'absolute',
|
|
81
|
-
top:
|
|
81
|
+
top: 0,
|
|
82
82
|
left: 0,
|
|
83
|
-
width: '100%'
|
|
83
|
+
width: '100%',
|
|
84
|
+
transform: "translateY(".concat(vItem.start, "px)")
|
|
84
85
|
},
|
|
85
86
|
key: "".concat(option.dsId),
|
|
86
87
|
innerRef: vItem.measureRef
|
|
@@ -105,8 +106,8 @@ const useItemRenderer = () => {
|
|
|
105
106
|
onClick: e => handleClick(option, e),
|
|
106
107
|
onMouseDown: handleOnMouseDown,
|
|
107
108
|
isActive: option.dsId === focusOptionIdx,
|
|
108
|
-
isSelected: isSelected(selectedValues, option)
|
|
109
|
-
|
|
109
|
+
isSelected: isSelected(selectedValues, option) //tabIndex={-1}
|
|
110
|
+
|
|
110
111
|
}));
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -21,7 +21,7 @@ const MultiSelectedValuesContainer = () => {
|
|
|
21
21
|
const correctPillsToShow = useGroupPills();
|
|
22
22
|
return useMemo(() => /*#__PURE__*/_jsx("div", {
|
|
23
23
|
style: {
|
|
24
|
-
width: 'max-content'
|
|
24
|
+
width: multiSelectedValue.length > 0 ? 'max-content' : '0px'
|
|
25
25
|
},
|
|
26
26
|
"data-testid": ComboboxDataTestid.SELECTED_VALUES
|
|
27
27
|
}, void 0, /*#__PURE__*/_jsx(DSPillGroupV2, {
|
|
@@ -25,6 +25,8 @@ const RemovableSelectedValuePill = props => {
|
|
|
25
25
|
onRemove: e => {
|
|
26
26
|
var _innerRef$current;
|
|
27
27
|
|
|
28
|
+
// preventing the menu to be opened
|
|
29
|
+
e.stopPropagation();
|
|
28
30
|
onChange(getSuggestedValueOnChange(pill, selectedValues), pill, e);
|
|
29
31
|
(_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.focus();
|
|
30
32
|
}
|
|
@@ -25,8 +25,11 @@ const useGroupPills = () => {
|
|
|
25
25
|
controlsWrapperRef,
|
|
26
26
|
pillGroupRef
|
|
27
27
|
} = useContext(ComboBoxContext);
|
|
28
|
-
const multiSelectedValues = selectedValues;
|
|
29
|
-
|
|
28
|
+
const multiSelectedValues = selectedValues; // 30 represent 30 pills maximum to calculate the grouped pill. this fix the load time issue
|
|
29
|
+
// when combobox is receiving a huge amount of options.
|
|
30
|
+
|
|
31
|
+
const selectedValuesLength = Math.min(30, multiSelectedValues.length);
|
|
32
|
+
const [pillsToShow, setPillsToShow] = useState(selectedValuesLength);
|
|
30
33
|
const {
|
|
31
34
|
width
|
|
32
35
|
} = useOnElementResize(controlsWrapperRef);
|
|
@@ -34,28 +37,28 @@ const useGroupPills = () => {
|
|
|
34
37
|
width: widthInput
|
|
35
38
|
} = useOnElementResize(innerRef || null);
|
|
36
39
|
useEffect(() => {
|
|
37
|
-
if (
|
|
38
|
-
setPillsToShow(
|
|
40
|
+
if (selectedValuesLength !== pillsToShow) {
|
|
41
|
+
setPillsToShow(selectedValuesLength);
|
|
39
42
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
43
|
|
|
41
|
-
}, [
|
|
44
|
+
}, [selectedValuesLength, width, widthInput]);
|
|
42
45
|
useLayoutEffect(() => {
|
|
43
|
-
if (selectedOptionsRef.current) {
|
|
46
|
+
if (selectedOptionsRef.current && pillGroupRef.current) {
|
|
44
47
|
if (pillGroupRef.current) pillGroupRef.current.style.width = 'max-content';
|
|
45
48
|
let lastPillFit = -1;
|
|
46
49
|
let currentWidth = 0;
|
|
47
50
|
const referenceWidth = selectedOptionsRef.current.offsetWidth;
|
|
48
|
-
const pills = [...
|
|
51
|
+
const pills = [...pillGroupRef.current.querySelectorAll(disabled ? '.ds-pill-wrapper-value' : '.ds-pill-wrapper-removable')];
|
|
49
52
|
const pillsWidth = pills.map(pill => pill === null || pill === void 0 ? void 0 : pill.offsetWidth);
|
|
50
53
|
pillsWidth.forEach((pillWidth, idx) => {
|
|
51
54
|
currentWidth += pillWidth;
|
|
52
55
|
|
|
53
|
-
if (currentWidth + getGroupedPillWidth(
|
|
56
|
+
if (currentWidth + getGroupedPillWidth(selectedValuesLength - idx - 1) <= referenceWidth) {
|
|
54
57
|
lastPillFit = idx;
|
|
55
58
|
}
|
|
56
59
|
});
|
|
57
60
|
|
|
58
|
-
if (!(
|
|
61
|
+
if (!(selectedValuesLength > 0 && pillsToShow !== selectedValuesLength)) {
|
|
59
62
|
const nextPillsToShow = lastPillFit + 1;
|
|
60
63
|
|
|
61
64
|
if (nextPillsToShow !== pillsToShow) {
|
|
@@ -65,7 +68,7 @@ const useGroupPills = () => {
|
|
|
65
68
|
|
|
66
69
|
if (pillGroupRef.current) pillGroupRef.current.style.width = 'fit-content';
|
|
67
70
|
}
|
|
68
|
-
}, [selectedOptionsRef, innerRef, multiSelectedValues, pillsToShow, pillGroupRef, width, widthInput, disabled]);
|
|
71
|
+
}, [selectedOptionsRef, innerRef, multiSelectedValues, pillsToShow, pillGroupRef, width, widthInput, disabled, selectedValuesLength]);
|
|
69
72
|
return pillsToShow || 1;
|
|
70
73
|
};
|
|
71
74
|
|
|
@@ -47,7 +47,8 @@ const getFirstOption = (options, selectedValues, inputValue) => {
|
|
|
47
47
|
|
|
48
48
|
for (let i = 0; i < options.length; i += 1) if (!['section', 'separator'].includes(options[i].type) && !options[i].disabled) {
|
|
49
49
|
return options[i].dsId;
|
|
50
|
-
}
|
|
50
|
+
} // list of disabled item results return ''
|
|
51
|
+
|
|
51
52
|
|
|
52
53
|
return '';
|
|
53
54
|
};
|
package/esm/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { DSAutocomplete, DSAutocompleteWithSchema } from './autocomplete/Autocomplete.js';
|
|
2
|
+
export { DSInputGroup, DSInputGroupWithSchema } from './input-group/InputGroup.js';
|
|
3
|
+
export { InputGroupDataTestIds } from './input-group/InputGroupDataTestIds.js';
|
|
2
4
|
export { DSControlledCheckbox, DSControlledCheckboxWithSchema } from './checkbox/ControlledCheckbox.js';
|
|
3
5
|
export { DSComboBox, DSComboBox as DSComboBoxV3, DSComboBoxWithSchema } from './combobox/ComboBox.js';
|
|
6
|
+
export { DSComboBoxName, DSComboboxSlots } from './combobox/theming.js';
|
|
7
|
+
export { ComboboxDataTestid } from './combobox/ComboboxDataTestids.js';
|
|
4
8
|
export { DSControlledDateRangePicker, DSControlledDateRangePickerWithSchema } from './date-range-picker/ControlledDateRangePicker.js';
|
|
5
9
|
export { ControlledDateRangePickerDatatestid } from './date-range-picker/ControlledDateRangePickerDatatestid.js';
|
|
6
10
|
export { CONTROLLED_DATE_RANGE_PICKER_TYPES } from './date-range-picker/ControlledDateRangePickerTypes.js';
|
|
@@ -14,7 +18,7 @@ export { getValidationTimeStringMetaInfo } from './date-time-picker/utils/timeHe
|
|
|
14
18
|
export { UsePhoneMaskWithSchema, getPhoneMaskedValue, usePhoneMask } from './mask-hook/hooks/usePhoneMask.js';
|
|
15
19
|
export { UseNumberMaskWithSchema, getNumberMaskedValue, useNumberMask } from './mask-hook/hooks/useNumberMask.js';
|
|
16
20
|
export { UseSSNMaskWithSchema, getSSNMaskedValue, useSSNMask } from './mask-hook/hooks/useSSNMask.js';
|
|
17
|
-
export { UseRegExpMaskWithSchema,
|
|
21
|
+
export { UseRegExpMaskWithSchema, useRegExpMask } from './mask-hook/hooks/useRegExpMask.js';
|
|
18
22
|
export { UseZipCodeMaskWithSchema, getUseZipMaskedValue, useZipCodeMask } from './mask-hook/hooks/useZipCodeMask.js';
|
|
19
23
|
export { DSInputText, DSInputTextWithSchema } from './text-input/DSInputText.js';
|
|
20
24
|
export { DSInputTextDataTestIds } from './text-input/exported-related/data-test-ids.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
4
|
+
import 'core-js/modules/esnext.async-iterator.for-each.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.for-each.js';
|
|
6
|
+
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
7
|
+
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
8
|
+
import { useMemo } from 'react';
|
|
9
|
+
import { describe, useValidateTypescriptPropTypes, useGetGlobalAttributes } from '@elliemae/ds-props-helpers';
|
|
10
|
+
import { StyledContainer, StyledLeftAddon, StyledInput, StyledRightAddon } from './styled.js';
|
|
11
|
+
import { propTypes } from './react-desc-prop-types.js';
|
|
12
|
+
import { InputGroupDataTestIds } from './InputGroupDataTestIds.js';
|
|
13
|
+
import { jsxs } from 'react/jsx-runtime';
|
|
14
|
+
|
|
15
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
16
|
+
|
|
17
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
18
|
+
|
|
19
|
+
const DSInputGroup = props => {
|
|
20
|
+
useValidateTypescriptPropTypes(props, propTypes);
|
|
21
|
+
const {
|
|
22
|
+
children,
|
|
23
|
+
leftAddon,
|
|
24
|
+
rightAddon
|
|
25
|
+
} = props;
|
|
26
|
+
const globals = useGetGlobalAttributes(props);
|
|
27
|
+
const cols = useMemo(() => {
|
|
28
|
+
if (leftAddon && rightAddon) {
|
|
29
|
+
return ['max-content', 'auto', 'max-content'];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (leftAddon && !rightAddon) {
|
|
33
|
+
return ['max-content', 'auto'];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!leftAddon && rightAddon) {
|
|
37
|
+
return ['auto', 'max-content'];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return ['auto'];
|
|
41
|
+
}, [leftAddon, rightAddon]);
|
|
42
|
+
return /*#__PURE__*/jsxs(StyledContainer, _objectSpread(_objectSpread({
|
|
43
|
+
cols: cols,
|
|
44
|
+
"data-testid": InputGroupDataTestIds.CONTAINER
|
|
45
|
+
}, globals), {}, {
|
|
46
|
+
children: [leftAddon && /*#__PURE__*/_jsx(StyledLeftAddon, {
|
|
47
|
+
"data-testid": InputGroupDataTestIds.LEFTADDON
|
|
48
|
+
}, void 0, leftAddon), /*#__PURE__*/_jsx(StyledInput, {
|
|
49
|
+
"data-testid": InputGroupDataTestIds.INPUTCONTAINER
|
|
50
|
+
}, void 0, children), rightAddon && /*#__PURE__*/_jsx(StyledRightAddon, {
|
|
51
|
+
"data-testid": InputGroupDataTestIds.RIGHTADDON
|
|
52
|
+
}, void 0, rightAddon)]
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const DSInputGroupWithSchema = describe(DSInputGroup);
|
|
57
|
+
DSInputGroupWithSchema.propTypes = propTypes;
|
|
58
|
+
|
|
59
|
+
export { DSInputGroup, DSInputGroupWithSchema };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PropTypes } from '@elliemae/ds-props-helpers';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
4
|
+
const propTypes = {
|
|
5
|
+
leftAddon: PropTypes.element.description('Component to be added at the left side of the input'),
|
|
6
|
+
rightAddon: PropTypes.element.description('Component to be added at the right side of the input'),
|
|
7
|
+
children: PropTypes.node.isRequired.description('React component to apply autocomplete functionality').defaultValue('')
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { propTypes };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Grid } from '@elliemae/ds-grid';
|
|
3
|
+
import '../text-input/DSInputText.js';
|
|
4
|
+
import { DSInputTextName, DSInputTextSlots } from '../text-input/exported-related/theming.js';
|
|
5
|
+
import '../combobox/ComboBox.js';
|
|
6
|
+
import { DSComboBoxName, DSComboboxSlots } from '../combobox/theming.js';
|
|
7
|
+
|
|
8
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
9
|
+
const StyledContainer = /*#__PURE__*/styled(Grid).withConfig({
|
|
10
|
+
componentId: "sc-12elcva-0"
|
|
11
|
+
})(["width:100%;height:28px;& > div:nth-child(1){.", "-", ",.", "-", ",.", "-", "{border-top-right-radius:0;border-bottom-right-radius:0;}}& > div:nth-child(2):nth-last-child(2){.", "-", ",.", "-", ",.", "-", "{border-radius:0;}}& > div:nth-child(2):nth-last-child(1){.", "-", ",.", "-", ",.", "-", "{border-top-left-radius:0;border-bottom-left-radius:0;}}"], DSInputTextName, DSInputTextSlots.INPUT_WRAPPER, DSInputTextName, DSInputTextSlots.INPUT, DSComboBoxName, DSComboboxSlots.INPUT_WRAPPER, DSInputTextName, DSInputTextSlots.INPUT_WRAPPER, DSInputTextName, DSInputTextSlots.INPUT, DSComboBoxName, DSComboboxSlots.INPUT_WRAPPER, DSInputTextName, DSInputTextSlots.INPUT_WRAPPER, DSInputTextName, DSInputTextSlots.INPUT, DSComboBoxName, DSComboboxSlots.INPUT_WRAPPER);
|
|
12
|
+
const StyledAddon = /*#__PURE__*/styled.div.withConfig({
|
|
13
|
+
componentId: "sc-12elcva-1"
|
|
14
|
+
})(["outline:1px solid ", ";outline-offset:-1px;height:inherit;display:flex;button{border-width:1px;}&:hover{z-index:1;button:not(:disabled){border:1px solid ", ";}}&:focus-within{z-index:1;}"], _ref => {
|
|
15
|
+
let {
|
|
16
|
+
theme
|
|
17
|
+
} = _ref;
|
|
18
|
+
return theme.colors.neutral['400'];
|
|
19
|
+
}, _ref2 => {
|
|
20
|
+
let {
|
|
21
|
+
theme
|
|
22
|
+
} = _ref2;
|
|
23
|
+
return theme.colors.brand['700'];
|
|
24
|
+
});
|
|
25
|
+
const StyledLeftAddon = /*#__PURE__*/styled(StyledAddon).withConfig({
|
|
26
|
+
componentId: "sc-12elcva-2"
|
|
27
|
+
})(["border-top-left-radius:2px;border-bottom-left-radius:2px;margin-right:-1px;&:hover{button:not(:disabled){border-top-right-radius:0px;border-bottom-right-radius:0px;}}"]);
|
|
28
|
+
const StyledRightAddon = /*#__PURE__*/styled(StyledAddon).withConfig({
|
|
29
|
+
componentId: "sc-12elcva-3"
|
|
30
|
+
})(["border-top-right-radius:2px;border-bottom-right-radius:2px;margin-left:-1px;&:hover{button:not(:disabled){border-top-left-radius:0px;border-bottom-left-radius:0px;}}"]);
|
|
31
|
+
const StyledInput = /*#__PURE__*/styled.div.withConfig({
|
|
32
|
+
componentId: "sc-12elcva-4"
|
|
33
|
+
})(["&:focus-within,&:hover{z-index:1;}"]);
|
|
34
|
+
|
|
35
|
+
export { StyledContainer, StyledInput, StyledLeftAddon, StyledRightAddon };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { UsePhoneMaskWithSchema, getPhoneMaskedValue, usePhoneMask } from './usePhoneMask.js';
|
|
2
2
|
export { UseNumberMaskWithSchema, getNumberMaskedValue, useNumberMask } from './useNumberMask.js';
|
|
3
3
|
export { UseSSNMaskWithSchema, getSSNMaskedValue, useSSNMask } from './useSSNMask.js';
|
|
4
|
-
export { UseRegExpMaskWithSchema,
|
|
4
|
+
export { UseRegExpMaskWithSchema, useRegExpMask } from './useRegExpMask.js';
|
|
5
5
|
export { UseZipCodeMaskWithSchema, getUseZipMaskedValue, useZipCodeMask } from './useZipCodeMask.js';
|
|
@@ -14,8 +14,8 @@ import 'core-js/modules/esnext.iterator.reduce.js';
|
|
|
14
14
|
import { DSMaskPhoneHookPropsTypes, DSMaskPhoneHookDefaultProps } from '../react-desc-prop-types.js';
|
|
15
15
|
|
|
16
16
|
const _excluded = ["valueSetter", "onChange", "onKeyDown", "onBlur"];
|
|
17
|
-
const phoneSpecialChars = [['(', 0], [') ', 4], ['-', 9]];
|
|
18
|
-
const internationalPhoneSpecialChars = [['+1 (', 0], [') ', 7], ['-', 12]];
|
|
17
|
+
const phoneSpecialChars = [['(', 0], [') ', 4], [' - ', 9]];
|
|
18
|
+
const internationalPhoneSpecialChars = [['+1 (', 0], [') ', 7], [' - ', 12]];
|
|
19
19
|
|
|
20
20
|
const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
|
|
21
21
|
const characters = rawValue.split(''); // Work with digits only
|
|
@@ -113,4 +113,4 @@ const useRegExpMask = props => {
|
|
|
113
113
|
const UseRegExpMaskWithSchema = describe(useRegExpMask);
|
|
114
114
|
UseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;
|
|
115
115
|
|
|
116
|
-
export { UseRegExpMaskWithSchema,
|
|
116
|
+
export { UseRegExpMaskWithSchema, useRegExpMask };
|
package/esm/mask-hook/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { UsePhoneMaskWithSchema, getPhoneMaskedValue, usePhoneMask } from './hooks/usePhoneMask.js';
|
|
2
2
|
export { UseNumberMaskWithSchema, getNumberMaskedValue, useNumberMask } from './hooks/useNumberMask.js';
|
|
3
3
|
export { UseSSNMaskWithSchema, getSSNMaskedValue, useSSNMask } from './hooks/useSSNMask.js';
|
|
4
|
-
export { UseRegExpMaskWithSchema,
|
|
4
|
+
export { UseRegExpMaskWithSchema, useRegExpMask } from './hooks/useRegExpMask.js';
|
|
5
5
|
export { UseZipCodeMaskWithSchema, getUseZipMaskedValue, useZipCodeMask } from './hooks/useZipCodeMask.js';
|
|
@@ -7,7 +7,7 @@ const readOnlyBorderCss = css(_templateObject2 || (_templateObject2 = _taggedTem
|
|
|
7
7
|
const disabledBorderCss = commonBorderCss;
|
|
8
8
|
const hasErrorBorderCss = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n"])), th.color('danger-900'));
|
|
9
9
|
const hoverBorderCss = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n"])), th.color('brand-700'));
|
|
10
|
-
const focusBorderCss = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n border: 1px solid transparent;\n outline: 2px solid ", ";\n outline-offset: -
|
|
10
|
+
const focusBorderCss = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n border: 1px solid transparent;\n outline: 2px solid ", ";\n outline-offset: -2px;\n"])), th.color('brand-700'));
|
|
11
11
|
const getBorderCss = props => {
|
|
12
12
|
if (props.isDisabled) return disabledBorderCss;
|
|
13
13
|
if (props.hasFocus) return focusBorderCss;
|