@elliemae/ds-controlled-form 2.3.2-next.0 → 2.4.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/autocomplete/parts/controls/useKeyboardNavigation.js +93 -0
- package/cjs/autocomplete/parts/controls/useMaskedOnChange.js +28 -0
- package/cjs/autocomplete/react-desc-prop-types.js +19 -0
- package/cjs/autocomplete/sharedTypes.js +2 -0
- package/cjs/combobox/config/useComboBox.js +30 -6
- package/cjs/combobox/config/useCorrectOptions.js +1 -1
- package/cjs/combobox/parts/container/Container.js +25 -33
- package/cjs/combobox/parts/controls/Controls.js +4 -16
- package/cjs/combobox/parts/controls-input/useControlsInput.js +1 -3
- package/cjs/combobox/parts/controls-input/useKeyboardNavigation.js +36 -30
- package/cjs/combobox/parts/header-list/HeaderList.js +3 -4
- package/cjs/combobox/parts/header-list/useHeaderListHandlers.js +18 -9
- package/cjs/combobox/parts/menu-list/MenuList.js +0 -2
- package/cjs/combobox/parts/menu-list/useItemRenderer.js +9 -14
- package/cjs/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +6 -17
- package/cjs/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +42 -0
- package/cjs/combobox/react-desc-prop-types.js +0 -2
- package/cjs/combobox/sharedTypes.js +3 -1
- package/cjs/combobox/utils/listHelper.js +47 -0
- package/cjs/mask-hook/hooks/useNumberMask.js +21 -17
- package/cjs/mask-hook/hooks/usePhoneMask.js +1 -1
- package/esm/autocomplete/parts/controls/useKeyboardNavigation.js +89 -0
- package/esm/autocomplete/parts/controls/useMaskedOnChange.js +24 -0
- package/esm/autocomplete/react-desc-prop-types.js +14 -0
- package/esm/autocomplete/sharedTypes.js +1 -0
- package/esm/combobox/config/useComboBox.js +31 -7
- package/esm/combobox/config/useCorrectOptions.js +1 -1
- package/esm/combobox/parts/container/Container.js +26 -34
- package/esm/combobox/parts/controls/Controls.js +4 -16
- package/esm/combobox/parts/controls-input/useControlsInput.js +1 -3
- package/esm/combobox/parts/controls-input/useKeyboardNavigation.js +38 -32
- package/esm/combobox/parts/header-list/HeaderList.js +3 -4
- package/esm/combobox/parts/header-list/useHeaderListHandlers.js +19 -10
- package/esm/combobox/parts/menu-list/MenuList.js +0 -2
- package/esm/combobox/parts/menu-list/useItemRenderer.js +10 -15
- package/esm/combobox/parts/multi-selected-values-container/MultiSelectedValuesContainer.js +6 -17
- package/esm/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.js +34 -0
- package/esm/combobox/react-desc-prop-types.js +0 -2
- package/esm/combobox/sharedTypes.js +3 -2
- package/esm/combobox/utils/listHelper.js +45 -1
- package/esm/mask-hook/hooks/useNumberMask.js +21 -17
- package/esm/mask-hook/hooks/usePhoneMask.js +1 -1
- package/package.json +35 -23
- package/types/autocomplete/parts/controls/useKeyboardNavigation.d.ts +4 -0
- package/types/autocomplete/parts/controls/useMaskedOnChange.d.ts +2 -0
- package/types/autocomplete/react-desc-prop-types.d.ts +54 -0
- package/types/autocomplete/sharedTypes.d.ts +20 -0
- package/types/combobox/parts/header-list/useHeaderListHandlers.d.ts +1 -1
- package/types/combobox/parts/multi-selected-values-container/RemovableSelectedValuePill.d.ts +5 -0
- package/types/combobox/react-desc-prop-types.d.ts +3 -4
- package/types/combobox/sharedTypes.d.ts +1 -0
- package/types/combobox/tests/{combobox-creatable.test.d.ts → creatable.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-disable.test.d.ts → disabled.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-general.test.d.ts → general.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-multi-select.test.d.ts → multi-select.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-onlyselectable.test.d.ts → onlyselectable.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-single-select.test.d.ts → single-select.test.d.ts} +0 -0
- package/types/combobox/tests/{combobox-usemask.test.d.ts → usemask.test.d.ts} +0 -0
- package/types/combobox/utils/listHelper.d.ts +3 -0
- package/cjs/combobox/utils/hooks/useKeyboardNavigation.js +0 -168
- package/cjs/combobox/utils/hooks/useOnElementResize.js +0 -37
- package/esm/combobox/utils/hooks/useKeyboardNavigation.js +0 -164
- package/esm/combobox/utils/hooks/useOnElementResize.js +0 -33
- package/types/combobox/utils/hooks/useKeyboardNavigation.d.ts +0 -4
- package/types/combobox/utils/hooks/useOnElementResize.d.ts +0 -3
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/esnext.async-iterator.find.js');
|
|
6
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.find.js');
|
|
8
|
+
var React = require('react');
|
|
9
|
+
var AutocompleteCTX = require('../../AutocompleteCTX.js');
|
|
10
|
+
var listHelper = require('../../utils/listHelper.js');
|
|
11
|
+
|
|
12
|
+
const isOptionFocuseable = opt => !['section', 'separator'].includes(opt.type);
|
|
13
|
+
|
|
14
|
+
const useKeyboardNavigation = () => {
|
|
15
|
+
const {
|
|
16
|
+
props: {
|
|
17
|
+
onValueChange,
|
|
18
|
+
options
|
|
19
|
+
},
|
|
20
|
+
setShowPopover,
|
|
21
|
+
showPopover,
|
|
22
|
+
focusOptionIdx,
|
|
23
|
+
setCurrentOption,
|
|
24
|
+
scrollOptionIntoView
|
|
25
|
+
} = React.useContext(AutocompleteCTX.AutocompleteContext);
|
|
26
|
+
const currentItemIndex = options.findIndex(opt => opt.dsId === focusOptionIdx);
|
|
27
|
+
const currentItem = options.find(item => item.type === 'option' && item.dsId === focusOptionIdx);
|
|
28
|
+
const selectOption = React.useCallback(e => {
|
|
29
|
+
if (onValueChange) onValueChange(currentItem.label, e);
|
|
30
|
+
setShowPopover(false);
|
|
31
|
+
}, [currentItem, setShowPopover, onValueChange]);
|
|
32
|
+
const onInputKeyDown = React.useCallback(e => {
|
|
33
|
+
const targetElement = e.target;
|
|
34
|
+
|
|
35
|
+
if (['ArrowDown', 'ArrowUp', 'Enter'].includes(e.key) || e.keyCode >= 48 && e.keyCode <= 90) {
|
|
36
|
+
setShowPopover(true);
|
|
37
|
+
} // =============================================================================
|
|
38
|
+
// ENTER AND SPACE KEY SELECT OPTIONS AND OPEN CLOSE THE POPOVER
|
|
39
|
+
// =============================================================================
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if (e.keyCode === 32 && targetElement.value === '' || e.key === 'Enter') {
|
|
43
|
+
if (showPopover) {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
selectOption(e);
|
|
46
|
+
}
|
|
47
|
+
} // =============================================================================
|
|
48
|
+
// ARROWS UP AND DOWN
|
|
49
|
+
// =============================================================================
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if (e.key === 'ArrowDown') {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
|
|
55
|
+
if (showPopover) {
|
|
56
|
+
const nextItemIndex = listHelper.findInCircularList(options, currentItemIndex, isOptionFocuseable);
|
|
57
|
+
setCurrentOption(options[nextItemIndex].dsId);
|
|
58
|
+
scrollOptionIntoView(options[nextItemIndex].dsId);
|
|
59
|
+
} else {
|
|
60
|
+
setShowPopover(true);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (e.key === 'ArrowUp') {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
|
|
67
|
+
if (showPopover) {
|
|
68
|
+
const nextItemIndex = listHelper.findInCircularList(options, currentItemIndex, isOptionFocuseable, -1);
|
|
69
|
+
setCurrentOption(options[nextItemIndex].dsId);
|
|
70
|
+
scrollOptionIntoView(options[nextItemIndex].dsId);
|
|
71
|
+
} else {
|
|
72
|
+
setShowPopover(true);
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
const nextItemIndex = listHelper.findInCircularList(options, 0, isOptionFocuseable, -1);
|
|
75
|
+
setCurrentOption(options[nextItemIndex].dsId);
|
|
76
|
+
scrollOptionIntoView(options[nextItemIndex].dsId);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
} // =============================================================================
|
|
80
|
+
// ESCAPE
|
|
81
|
+
// =============================================================================
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if (e.key === 'Escape') {
|
|
85
|
+
setShowPopover(false);
|
|
86
|
+
}
|
|
87
|
+
}, [scrollOptionIntoView, currentItemIndex, options, showPopover, setCurrentOption, setShowPopover, selectOption]);
|
|
88
|
+
return {
|
|
89
|
+
onInputKeyDown
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
exports.useKeyboardNavigation = useKeyboardNavigation;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var AutocompleteCTX = require('../../AutocompleteCTX.js');
|
|
7
|
+
|
|
8
|
+
const useMaskedOnChange = () => {
|
|
9
|
+
const {
|
|
10
|
+
props: {
|
|
11
|
+
useMask,
|
|
12
|
+
onChange
|
|
13
|
+
},
|
|
14
|
+
setShowPopover
|
|
15
|
+
} = React.useContext(AutocompleteCTX.AutocompleteContext); // default onchange when no mask provided
|
|
16
|
+
|
|
17
|
+
const handleOnChange = React.useCallback(e => {
|
|
18
|
+
setShowPopover(true);
|
|
19
|
+
onChange(e.target.value);
|
|
20
|
+
}, [onChange, setShowPopover]);
|
|
21
|
+
const onChangeMask = useMask({
|
|
22
|
+
valueSetter: setInputValue,
|
|
23
|
+
onChange: handleOnChange
|
|
24
|
+
});
|
|
25
|
+
return (onChangeMask === null || onChangeMask === void 0 ? void 0 : onChangeMask.onChange) || handleOnChange;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.useMaskedOnChange = useMaskedOnChange;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
6
|
+
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
8
|
+
function noop() {}
|
|
9
|
+
const propTypes = {
|
|
10
|
+
placeholder: dsPropsHelpers.PropTypes.string.description('input s placeholder value').defaultValue(''),
|
|
11
|
+
options: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.array, dsPropsHelpers.PropTypes.object]).description('List of options').defaultValue([]),
|
|
12
|
+
value: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.string]).description('Array of option or single option selected'),
|
|
13
|
+
autoFocus: dsPropsHelpers.PropTypes.bool.description('Whether the combo box uses auto focus or not').defaultValue('false'),
|
|
14
|
+
hasError: dsPropsHelpers.PropTypes.bool.description('Whether the combo box has error or not').defaultValue('false'),
|
|
15
|
+
onChange: dsPropsHelpers.PropTypes.func.description('function triggered when an option is selected it will send the options selected').defaultValue('')
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.noop = noop;
|
|
19
|
+
exports.propTypes = propTypes;
|
|
@@ -15,6 +15,7 @@ var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
|
15
15
|
var ComboBoxCTX = require('../ComboBoxCTX.js');
|
|
16
16
|
var reactDescPropTypes = require('../react-desc-prop-types.js');
|
|
17
17
|
var useCorrectOptions = require('./useCorrectOptions.js');
|
|
18
|
+
var listHelper = require('../utils/listHelper.js');
|
|
18
19
|
|
|
19
20
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
20
21
|
|
|
@@ -35,15 +36,17 @@ const useComboBox = props => {
|
|
|
35
36
|
const [showSelectedOptions, setShowSelectedOptions] = React.useState(false);
|
|
36
37
|
const [inputValue, setInputValue] = React.useState('');
|
|
37
38
|
const [hasFocus, setHasFocus] = React.useState(false);
|
|
38
|
-
const [focusOptionIdx, setFocusOptionIdx] = React.useState('');
|
|
39
39
|
const listRef = React.useRef(null);
|
|
40
40
|
const wrapperListRef = React.useRef(null);
|
|
41
41
|
const selectedOptionsRef = React.useRef(null);
|
|
42
42
|
const controlsWrapperRef = React.useRef(null);
|
|
43
43
|
const selectAllCheckboxRef = React.useRef(null);
|
|
44
44
|
const toggleSelectionButtonRef = React.useRef(null);
|
|
45
|
-
const pillGroupRef = React.useRef(null);
|
|
46
|
-
|
|
45
|
+
const pillGroupRef = React.useRef(null);
|
|
46
|
+
const {
|
|
47
|
+
selectedValues
|
|
48
|
+
} = propsWithDefaults; // ---------------------------------------------------------------------------
|
|
49
|
+
// Menu Options with/out selected filter and creatable functionality
|
|
47
50
|
// ---------------------------------------------------------------------------
|
|
48
51
|
|
|
49
52
|
const correctOptions = useCorrectOptions.useCorrectOptions(propsWithDefaults, inputValue, showSelectedOptions); // ===========================================================================
|
|
@@ -59,9 +62,30 @@ const useComboBox = props => {
|
|
|
59
62
|
// Scroll into view function
|
|
60
63
|
// ===========================================================================
|
|
61
64
|
|
|
62
|
-
const scrollOptionIntoView = React.useCallback(dsId
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const scrollOptionIntoView = React.useCallback(function (dsId) {
|
|
66
|
+
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
67
|
+
align: 'center'
|
|
68
|
+
};
|
|
69
|
+
virtualListHelpers.scrollToIndex(correctOptions.findIndex(opt => opt.dsId === dsId), // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
70
|
+
opts);
|
|
71
|
+
}, [correctOptions, virtualListHelpers]); // ===========================================================================
|
|
72
|
+
// Init focused option when opening the menu list
|
|
73
|
+
// ===========================================================================
|
|
74
|
+
|
|
75
|
+
const [focusOptionIdx, setFocusOptionIdx] = React.useState('');
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
// we are updating the focus option only when we have focus on the input and
|
|
78
|
+
// we are in the selected option view or we are typing to force first option always
|
|
79
|
+
if (hasFocus && (focusOptionIdx === '' || inputValue !== '' || showSelectedOptions)) {
|
|
80
|
+
const focusedValue = listHelper.getFirstOption(correctOptions, selectedValues, inputValue);
|
|
81
|
+
setFocusOptionIdx(focusedValue);
|
|
82
|
+
scrollOptionIntoView(focusedValue, {
|
|
83
|
+
align: 'center'
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!hasFocus) setFocusOptionIdx(''); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
88
|
+
}, [showPopover, hasFocus, correctOptions, selectedValues, inputValue]);
|
|
65
89
|
const ctx = React.useMemo(() => ({
|
|
66
90
|
props: _objectSpread(_objectSpread({}, propsWithDefaults), {}, {
|
|
67
91
|
options: correctOptions
|
|
@@ -53,7 +53,7 @@ const useCorrectOptions = (propsWithDefaults, inputValue, showSelectedOptions) =
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (onCreate && inputValue && options.findIndex(option => option.type === constants.MENU_OPTION_TYPES.OPTION && option.label === inputValue) === -1) {
|
|
56
|
-
const creatableUuid = uid.uid(
|
|
56
|
+
const creatableUuid = uid.uid();
|
|
57
57
|
const creatableItem = {
|
|
58
58
|
dsId: "creatable-".concat(creatableUuid),
|
|
59
59
|
label: inputValue,
|
|
@@ -56,7 +56,7 @@ const Container = () => {
|
|
|
56
56
|
const StyledContainer = inline ? styled.StyledContainerInline : styled.StyledContainerWithPopper;
|
|
57
57
|
const globalAttributes = dsPropsHelpers.useGetGlobalAttributes(props); // Removing possible collisionable props
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const globalsAttrs = _objectWithoutProperties__default["default"](globalAttributes, _excluded);
|
|
60
60
|
|
|
61
61
|
const handleMouseDown = React.useCallback(e => {
|
|
62
62
|
e.preventDefault();
|
|
@@ -76,38 +76,30 @@ const Container = () => {
|
|
|
76
76
|
React.useEffect(() => {
|
|
77
77
|
if (onMenuOpen && showPopover) onMenuOpen();else if (onMenuClose && !showPopover) onMenuClose();
|
|
78
78
|
}, [showPopover, onMenuOpen, onMenuClose]);
|
|
79
|
-
return React.useMemo(() => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
zIndex: zIndex
|
|
104
|
-
}, void 0, _StyledPopperWrapper || (_StyledPopperWrapper = /*#__PURE__*/_jsx__default["default"](styled.StyledPopperWrapper, {
|
|
105
|
-
tabIndex: -1,
|
|
106
|
-
onMouseDown: handleMouseDown
|
|
107
|
-
}, void 0, _MenuList2 || (_MenuList2 = /*#__PURE__*/_jsx__default["default"](MenuList.MenuList, {})))))]
|
|
108
|
-
}))
|
|
109
|
-
});
|
|
110
|
-
}, [inline, showPopover, StyledContainer, placementOrderPreference, referenceElement, rest, startPlacementPreference, withoutPortal, zIndex, handleCloseMenu, handleMouseDown, setReferenceElement]);
|
|
79
|
+
return React.useMemo(() => /*#__PURE__*/jsxRuntime.jsx(StyledContainer, _objectSpread(_objectSpread({
|
|
80
|
+
"data-testid": ComboboxDataTestids.ComboboxDataTestid.CONTAINER,
|
|
81
|
+
ref: setReferenceElement
|
|
82
|
+
}, globalsAttrs), {}, {
|
|
83
|
+
children: inline ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
84
|
+
children: [_Controls || (_Controls = /*#__PURE__*/_jsx__default["default"](Controls.Controls, {})), _MenuList || (_MenuList = /*#__PURE__*/_jsx__default["default"](MenuList.MenuList, {}))]
|
|
85
|
+
}) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
86
|
+
children: [_Controls2 || (_Controls2 = /*#__PURE__*/_jsx__default["default"](Controls.Controls, {})), /*#__PURE__*/_jsx__default["default"](dsPopperjs.DSPopperJS, {
|
|
87
|
+
customOffset: [0, 5],
|
|
88
|
+
referenceElement: referenceElement,
|
|
89
|
+
showPopover: showPopover,
|
|
90
|
+
closeContextMenu: handleCloseMenu,
|
|
91
|
+
startPlacementPreference: startPlacementPreference,
|
|
92
|
+
placementOrderPreference: placementOrderPreference,
|
|
93
|
+
withoutPortal: withoutPortal,
|
|
94
|
+
withoutArrow: true,
|
|
95
|
+
withoutAnimation: true,
|
|
96
|
+
zIndex: zIndex
|
|
97
|
+
}, void 0, _StyledPopperWrapper || (_StyledPopperWrapper = /*#__PURE__*/_jsx__default["default"](styled.StyledPopperWrapper, {
|
|
98
|
+
tabIndex: -1,
|
|
99
|
+
onMouseDown: handleMouseDown
|
|
100
|
+
}, void 0, _MenuList2 || (_MenuList2 = /*#__PURE__*/_jsx__default["default"](MenuList.MenuList, {})))))]
|
|
101
|
+
})
|
|
102
|
+
})), [inline, StyledContainer, setReferenceElement, globalsAttrs, referenceElement, showPopover, handleCloseMenu, startPlacementPreference, placementOrderPreference, withoutPortal, zIndex, handleMouseDown]);
|
|
111
103
|
};
|
|
112
104
|
|
|
113
105
|
exports.Container = Container;
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _jsx = require('@babel/runtime/helpers/jsx');
|
|
6
6
|
var React = require('react');
|
|
7
|
-
var dsPills = require('@elliemae/ds-pills');
|
|
8
7
|
var DropdownIndicator = require('../DropdownIndicator.js');
|
|
9
8
|
var ComboboxDataTestids = require('../../ComboboxDataTestids.js');
|
|
10
9
|
var ComboBoxCTX = require('../../ComboBoxCTX.js');
|
|
@@ -14,6 +13,7 @@ var ControlsInput = require('../controls-input/ControlsInput.js');
|
|
|
14
13
|
var useOnPillsNavigation = require('./useOnPillsNavigation.js');
|
|
15
14
|
var A11yFocusedOption = require('../A11yFocusedOption.js');
|
|
16
15
|
var A11ySelectedValues = require('../A11ySelectedValues.js');
|
|
16
|
+
var RemovableSelectedValuePill = require('../multi-selected-values-container/RemovableSelectedValuePill.js');
|
|
17
17
|
var jsxRuntime = require('react/jsx-runtime');
|
|
18
18
|
|
|
19
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -25,7 +25,6 @@ const Controls = () => {
|
|
|
25
25
|
const {
|
|
26
26
|
props: {
|
|
27
27
|
inline,
|
|
28
|
-
onChange,
|
|
29
28
|
disabled,
|
|
30
29
|
inputMinWidth,
|
|
31
30
|
hasError,
|
|
@@ -91,20 +90,9 @@ const Controls = () => {
|
|
|
91
90
|
onClick: handleOnPillsClick,
|
|
92
91
|
children: [_A11ySelectedValues || (_A11ySelectedValues = /*#__PURE__*/_jsx__default["default"](A11ySelectedValues.A11ySelectedValues, {})), _A11yFocusedOption || (_A11yFocusedOption = /*#__PURE__*/_jsx__default["default"](A11yFocusedOption.A11yFocusedOption, {})), Array.isArray(selectedValues) ? _MultiSelectedValuesC || (_MultiSelectedValuesC = /*#__PURE__*/_jsx__default["default"](MultiSelectedValuesContainer.MultiSelectedValuesContainer, {})) : /*#__PURE__*/_jsx__default["default"]("div", {
|
|
93
92
|
"data-testid": ComboboxDataTestids.ComboboxDataTestid.SELECTED_VALUES
|
|
94
|
-
}, void 0, selectedValues && /*#__PURE__*/_jsx__default["default"](
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
tabIndex: -1,
|
|
98
|
-
disabled: disabled,
|
|
99
|
-
label: selectedValues.label,
|
|
100
|
-
type: disabled ? 'value' : 'removable',
|
|
101
|
-
onRemove: () => {
|
|
102
|
-
var _innerRef$current4;
|
|
103
|
-
|
|
104
|
-
onChange(null);
|
|
105
|
-
(_innerRef$current4 = innerRef.current) === null || _innerRef$current4 === void 0 ? void 0 : _innerRef$current4.focus();
|
|
106
|
-
}
|
|
107
|
-
}, selectedValues.value))]
|
|
93
|
+
}, void 0, selectedValues && /*#__PURE__*/_jsx__default["default"](RemovableSelectedValuePill.RemovableSelectedValuePill, {
|
|
94
|
+
pill: selectedValues
|
|
95
|
+
}))]
|
|
108
96
|
}), _ControlsInput || (_ControlsInput = /*#__PURE__*/_jsx__default["default"](ControlsInput.ControlsInput, {})), !inline && /*#__PURE__*/_jsx__default["default"](styled.StyledHeaderActionsWrapper, {
|
|
109
97
|
justifyContent: "center",
|
|
110
98
|
cols: ['auto', 'auto']
|
|
@@ -17,7 +17,6 @@ const useControlsInput = () => {
|
|
|
17
17
|
onFilter
|
|
18
18
|
},
|
|
19
19
|
setHasFocus,
|
|
20
|
-
setFocusOptionIdx,
|
|
21
20
|
inputValue,
|
|
22
21
|
setInputValue,
|
|
23
22
|
setShowSelectedOptions
|
|
@@ -38,10 +37,9 @@ const useControlsInput = () => {
|
|
|
38
37
|
const handleOnBlur = React.useCallback(() => {
|
|
39
38
|
setInputValue('');
|
|
40
39
|
if (onFilter) onFilter('');
|
|
41
|
-
setFocusOptionIdx('');
|
|
42
40
|
setHasFocus(false);
|
|
43
41
|
setShowSelectedOptions(false);
|
|
44
|
-
}, [setInputValue, setShowSelectedOptions, onFilter,
|
|
42
|
+
}, [setInputValue, setShowSelectedOptions, onFilter, setHasFocus]);
|
|
45
43
|
const handleOnFocus = React.useCallback(() => {
|
|
46
44
|
setHasFocus(true);
|
|
47
45
|
}, [setHasFocus]);
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
require('core-js/modules/esnext.async-iterator.find.js');
|
|
6
6
|
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
7
|
require('core-js/modules/esnext.iterator.find.js');
|
|
8
|
+
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
9
|
+
require('core-js/modules/esnext.iterator.filter.js');
|
|
8
10
|
var React = require('react');
|
|
9
11
|
var ComboBoxCTX = require('../../ComboBoxCTX.js');
|
|
10
12
|
var listHelper = require('../../utils/listHelper.js');
|
|
@@ -15,47 +17,38 @@ const isOptionFocuseable = opt => !['section', 'separator'].includes(opt.type) &
|
|
|
15
17
|
const useKeyboardNavigation = () => {
|
|
16
18
|
const {
|
|
17
19
|
props: {
|
|
18
|
-
inline,
|
|
19
|
-
onSelectAll,
|
|
20
20
|
onCancel,
|
|
21
21
|
onKeyDown,
|
|
22
22
|
onChange,
|
|
23
23
|
onCreate,
|
|
24
|
+
onFilter,
|
|
25
|
+
onSelectAll,
|
|
26
|
+
inline,
|
|
24
27
|
options,
|
|
25
28
|
selectedValues,
|
|
26
|
-
onFilter,
|
|
27
29
|
withoutPortal
|
|
28
30
|
},
|
|
29
|
-
setShowPopover,
|
|
30
|
-
setInputValue,
|
|
31
31
|
inputValue,
|
|
32
32
|
showPopover,
|
|
33
33
|
focusOptionIdx,
|
|
34
|
-
setFocusOptionIdx,
|
|
35
34
|
selectAllCheckboxRef,
|
|
36
|
-
toggleSelectionButtonRef
|
|
35
|
+
toggleSelectionButtonRef,
|
|
36
|
+
setShowPopover,
|
|
37
|
+
setInputValue,
|
|
38
|
+
scrollOptionIntoView,
|
|
39
|
+
setFocusOptionIdx
|
|
37
40
|
} = React.useContext(ComboBoxCTX.ComboBoxContext);
|
|
38
41
|
const multiple = Array.isArray(selectedValues);
|
|
39
42
|
const selectableOptions = listHelper.getOptions(options);
|
|
40
43
|
const currentItemIndex = options.findIndex(opt => opt.dsId === focusOptionIdx);
|
|
41
44
|
const currentItem = options.find(item => item.dsId === focusOptionIdx);
|
|
42
|
-
const selectOption = React.useCallback(() => {
|
|
43
|
-
const selectedOption = options.find(item => item.dsId === focusOptionIdx);
|
|
44
|
-
|
|
45
|
-
if (!selectedOption.disabled) {
|
|
46
|
-
if (onFilter) onFilter('');
|
|
47
|
-
setInputValue('');
|
|
48
|
-
onChange(selectedOption);
|
|
49
|
-
if (!multiple) setShowPopover(false);
|
|
50
|
-
}
|
|
51
|
-
}, [multiple, options, setInputValue, focusOptionIdx, setShowPopover, onFilter, onChange]);
|
|
52
45
|
const onInputKeyDown = React.useCallback(e => {
|
|
53
46
|
// =============================================================================
|
|
54
47
|
// CUSTOM KEYS
|
|
55
48
|
// =============================================================================
|
|
56
|
-
if (onKeyDown) onKeyDown(e, currentItem);
|
|
49
|
+
if (onKeyDown && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === constants.MENU_OPTION_TYPES.OPTION) onKeyDown(e, currentItem);
|
|
57
50
|
|
|
58
|
-
if (
|
|
51
|
+
if (['ArrowDown', 'ArrowUp', 'Enter', 'Spacebar'].includes(e.key) || e.keyCode >= 48 && e.keyCode <= 90) {
|
|
59
52
|
setShowPopover(true);
|
|
60
53
|
} // =============================================================================
|
|
61
54
|
// ESCAPE
|
|
@@ -90,8 +83,17 @@ const useKeyboardNavigation = () => {
|
|
|
90
83
|
e.preventDefault();
|
|
91
84
|
e.stopPropagation();
|
|
92
85
|
|
|
93
|
-
if (focusOptionIdx !== '' && showPopover) {
|
|
94
|
-
|
|
86
|
+
if (focusOptionIdx !== '' && showPopover && (currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === constants.MENU_OPTION_TYPES.OPTION) {
|
|
87
|
+
if ((currentItem === null || currentItem === void 0 ? void 0 : currentItem.type) === 'option' && !currentItem.disabled) {
|
|
88
|
+
if (onFilter) onFilter('');
|
|
89
|
+
setInputValue('');
|
|
90
|
+
|
|
91
|
+
if (!multiple) {
|
|
92
|
+
setShowPopover(false);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
onChange(listHelper.getSuggestedValueOnChange(currentItem, selectedValues), currentItem, e);
|
|
96
|
+
}
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -99,8 +101,8 @@ const useKeyboardNavigation = () => {
|
|
|
99
101
|
setShowPopover(false);
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
if (e.key === 'a' && e.ctrlKey && multiple) {
|
|
103
|
-
|
|
104
|
+
if (e.key === 'a' && e.ctrlKey && multiple && onSelectAll) {
|
|
105
|
+
onSelectAll(options.filter(option => option.type === 'option' && !option.disabled), e);
|
|
104
106
|
} // =============================================================================
|
|
105
107
|
// ARROWS UP AND DOWN: LOGIC TO CALCULATE NEXT OR PREV ITEM TO PSEUDOFOCUS FROM INPUT
|
|
106
108
|
// =============================================================================
|
|
@@ -113,6 +115,7 @@ const useKeyboardNavigation = () => {
|
|
|
113
115
|
if ((showPopover || inline) && selectableOptions.length) {
|
|
114
116
|
const nextItemIndex = listHelper.findInCircularList(options, currentItemIndex, isOptionFocuseable);
|
|
115
117
|
setFocusOptionIdx(options[nextItemIndex].dsId);
|
|
118
|
+
scrollOptionIntoView(options[nextItemIndex].dsId);
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
@@ -124,11 +127,13 @@ const useKeyboardNavigation = () => {
|
|
|
124
127
|
|
|
125
128
|
if (showPopover || inline) {
|
|
126
129
|
setFocusOptionIdx(options[prevItemIndex].dsId);
|
|
130
|
+
scrollOptionIntoView(options[prevItemIndex].dsId);
|
|
127
131
|
} else {
|
|
128
132
|
setShowPopover(true);
|
|
129
133
|
setTimeout(() => {
|
|
130
|
-
const
|
|
131
|
-
setFocusOptionIdx(options[
|
|
134
|
+
const prevItem = listHelper.findInCircularList(options, 0, isOptionFocuseable, -1);
|
|
135
|
+
setFocusOptionIdx(options[prevItem].dsId);
|
|
136
|
+
scrollOptionIntoView(options[prevItem].dsId);
|
|
132
137
|
});
|
|
133
138
|
}
|
|
134
139
|
} // =============================================================================
|
|
@@ -137,10 +142,10 @@ const useKeyboardNavigation = () => {
|
|
|
137
142
|
|
|
138
143
|
|
|
139
144
|
if (e.key === 'Backspace' && inputValue.length <= 0 && !inline) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
onChange(
|
|
145
|
+
const lastValue = listHelper.getLastValueSelected(selectedValues);
|
|
146
|
+
|
|
147
|
+
if (!inputValue && lastValue) {
|
|
148
|
+
onChange(listHelper.getSuggestedValueOnChange(lastValue, selectedValues), lastValue, e);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
if (onFilter) onFilter('');
|
|
@@ -159,7 +164,8 @@ const useKeyboardNavigation = () => {
|
|
|
159
164
|
// if (e.key === 'Tab' && multiple) {
|
|
160
165
|
// }
|
|
161
166
|
|
|
162
|
-
},
|
|
167
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
168
|
+
[onKeyDown, currentItem, onCreate, multiple, inputValue, inline, withoutPortal, setShowPopover, onCancel, onFilter, setInputValue, focusOptionIdx, showPopover, selectableOptions.length, options, currentItemIndex, setFocusOptionIdx, selectedValues, onChange, selectAllCheckboxRef, toggleSelectionButtonRef]);
|
|
163
169
|
return {
|
|
164
170
|
onInputKeyDown
|
|
165
171
|
};
|
|
@@ -21,9 +21,8 @@ var _StyledNoOptionsSelec;
|
|
|
21
21
|
const HeaderList = () => {
|
|
22
22
|
const {
|
|
23
23
|
props: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
selectedValues
|
|
24
|
+
selectedValues,
|
|
25
|
+
onSelectAll
|
|
27
26
|
},
|
|
28
27
|
showSelectedOptions,
|
|
29
28
|
selectAllCheckboxRef,
|
|
@@ -42,7 +41,7 @@ const HeaderList = () => {
|
|
|
42
41
|
return /*#__PURE__*/_jsx__default["default"](styled.StyledHeaderListWrapper, {
|
|
43
42
|
onKeyDown: handleKeyDown,
|
|
44
43
|
onMouseDown: handleOnMouseDown
|
|
45
|
-
}, void 0, /*#__PURE__*/_jsx__default["default"](styled.StyledSelectAllCheckbox, {}, void 0, onSelectAll &&
|
|
44
|
+
}, void 0, /*#__PURE__*/_jsx__default["default"](styled.StyledSelectAllCheckbox, {}, void 0, onSelectAll && /*#__PURE__*/_jsx__default["default"](ControlledCheckbox.DSControlledCheckbox, {
|
|
46
45
|
checked: checkboxStatus,
|
|
47
46
|
"aria-controls": checkboxStatus === 'mixed' ? multiSelectedValues.map(item => item.dsId).join(' ') : '',
|
|
48
47
|
name: "select-all-checkbox",
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
require('core-js/modules/web.dom-collections.iterator.js');
|
|
6
|
+
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
8
|
+
require('core-js/modules/esnext.iterator.filter.js');
|
|
5
9
|
var React = require('react');
|
|
6
10
|
var listHelper = require('../../utils/listHelper.js');
|
|
7
11
|
var ComboBoxCTX = require('../../ComboBoxCTX.js');
|
|
@@ -12,7 +16,6 @@ const useHeaderListHandlers = () => {
|
|
|
12
16
|
selectedValues,
|
|
13
17
|
options,
|
|
14
18
|
onSelectAll,
|
|
15
|
-
onClearAll,
|
|
16
19
|
innerRef
|
|
17
20
|
},
|
|
18
21
|
showSelectedOptions,
|
|
@@ -21,8 +24,8 @@ const useHeaderListHandlers = () => {
|
|
|
21
24
|
} = React.useContext(ComboBoxCTX.ComboBoxContext);
|
|
22
25
|
const multiSelectedValues = selectedValues;
|
|
23
26
|
const selectableOptions = listHelper.getSelectableOptions(options);
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
27
|
+
const getCheckboxStatus = React.useMemo(() => {
|
|
28
|
+
if (multiSelectedValues.length === selectableOptions.length) {
|
|
26
29
|
return true;
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -31,17 +34,23 @@ const useHeaderListHandlers = () => {
|
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
return 'mixed';
|
|
34
|
-
}, [multiSelectedValues, selectableOptions]);
|
|
37
|
+
}, [multiSelectedValues.length, selectableOptions.length]);
|
|
38
|
+
const [checkboxStatus, setCheckboxStatus] = React.useState(false);
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
setCheckboxStatus(getCheckboxStatus);
|
|
41
|
+
}, [getCheckboxStatus, multiSelectedValues]);
|
|
35
42
|
const handleOnMouseDown = React.useCallback(e => {
|
|
36
43
|
e.preventDefault(); // this prevent the input control to lose focus
|
|
37
44
|
}, []);
|
|
38
|
-
const handleSelectAllCheckboxChange = React.useCallback(
|
|
45
|
+
const handleSelectAllCheckboxChange = React.useCallback(e => {
|
|
39
46
|
if ((!checkboxStatus || checkboxStatus === 'mixed') && onSelectAll) {
|
|
40
|
-
onSelectAll();
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
onSelectAll(options.filter(option => option.type === 'option' && !option.disabled), e);
|
|
48
|
+
setCheckboxStatus(true);
|
|
49
|
+
} else if (onSelectAll) {
|
|
50
|
+
onSelectAll([], e);
|
|
51
|
+
setCheckboxStatus(false);
|
|
43
52
|
}
|
|
44
|
-
}, [checkboxStatus, onSelectAll,
|
|
53
|
+
}, [checkboxStatus, onSelectAll, options]);
|
|
45
54
|
const handleToggleSelectedValuesFilter = React.useCallback(e => {
|
|
46
55
|
e.preventDefault();
|
|
47
56
|
setShowSelectedOptions(!showSelectedOptions);
|
|
@@ -9,7 +9,6 @@ var ComboboxDataTestids = require('../../ComboboxDataTestids.js');
|
|
|
9
9
|
var ComboBoxCTX = require('../../ComboBoxCTX.js');
|
|
10
10
|
var HeaderList = require('../header-list/HeaderList.js');
|
|
11
11
|
var useItemRenderer = require('./useItemRenderer.js');
|
|
12
|
-
var useMenuListSetFocusOption = require('./useMenuListSetFocusOption.js');
|
|
13
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
14
13
|
|
|
15
14
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -36,7 +35,6 @@ const MenuList = () => {
|
|
|
36
35
|
const multiple = Array.isArray(selectedValues);
|
|
37
36
|
const withHeader = !inline && multiple && options.length > 0 && inputValue === '';
|
|
38
37
|
const ItemRenderer = useItemRenderer.useItemRenderer();
|
|
39
|
-
useMenuListSetFocusOption.useMenuListSetFocusOption();
|
|
40
38
|
const preventLoseInputFocus = React.useCallback(e => {
|
|
41
39
|
e.preventDefault();
|
|
42
40
|
}, []);
|
|
@@ -56,28 +56,23 @@ const useItemRenderer = () => {
|
|
|
56
56
|
setInputValue('');
|
|
57
57
|
onFilter('');
|
|
58
58
|
}
|
|
59
|
+
} else if (option.type === constants.MENU_OPTION_TYPES.OPTION) {
|
|
60
|
+
if (!option.disabled) {
|
|
61
|
+
if (onFilter) onFilter('');
|
|
62
|
+
setInputValue('');
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!option.disabled) {
|
|
64
|
-
var _innerRef$current;
|
|
64
|
+
if (!multiple) {
|
|
65
|
+
setShowPopover(false);
|
|
66
|
+
}
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
setShowPopover(false);
|
|
68
|
+
onChange(listHelper.getSuggestedValueOnChange(option, selectedValues), option, e);
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
if (onFilter) onFilter('');
|
|
71
|
-
setInputValue('');
|
|
72
|
-
onChange(option); // if we are focus in the header list we go back to the input
|
|
73
|
-
|
|
74
|
-
(_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.focus();
|
|
75
70
|
} // prevent for loosing focus on input control
|
|
76
71
|
|
|
77
72
|
|
|
78
73
|
e.stopPropagation();
|
|
79
74
|
e.preventDefault();
|
|
80
|
-
}, [onFilter, onChange, setShowPopover, multiple, innerRef]); // prevent blur from controls input
|
|
75
|
+
}, [onFilter, selectedValues, onChange, setShowPopover, multiple, innerRef]); // prevent blur from controls input
|
|
81
76
|
|
|
82
77
|
const handleOnMouseDown = React.useCallback(e => {
|
|
83
78
|
e.preventDefault();
|