@dhis2-ui/select 10.9.1 → 10.10.0-alpha.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/build/cjs/index.js +18 -4
- package/build/cjs/locales/en/translations.json +7 -5
- package/build/cjs/simple-single-select/__stories__/DefaultPosition.js +38 -0
- package/build/cjs/simple-single-select/__stories__/Dense.js +22 -0
- package/build/cjs/simple-single-select/__stories__/Empty.js +20 -0
- package/build/cjs/simple-single-select/__stories__/EmptyWithEmptyNode.js +28 -0
- package/build/cjs/simple-single-select/__stories__/EmptyWithEmptyText.js +21 -0
- package/build/cjs/simple-single-select/__stories__/FlippedPosition.js +37 -0
- package/build/cjs/simple-single-select/__stories__/InfiniteLoading.js +61 -0
- package/build/cjs/simple-single-select/__stories__/Loading.js +20 -0
- package/build/cjs/simple-single-select/__stories__/ShiftedIntoView.js +28 -0
- package/build/cjs/simple-single-select/__stories__/WithClearButton.js +25 -0
- package/build/cjs/simple-single-select/__stories__/WithCustomLowMaxHeight.js +22 -0
- package/build/cjs/simple-single-select/__stories__/WithCustomOptions.js +48 -0
- package/build/cjs/simple-single-select/__stories__/WithDisabledOption.js +28 -0
- package/build/cjs/simple-single-select/__stories__/WithFilterField.js +36 -0
- package/build/cjs/simple-single-select/__stories__/WithInitialFocus.js +38 -0
- package/build/cjs/simple-single-select/__stories__/WithManyOptions.js +24 -0
- package/build/cjs/simple-single-select/__stories__/WithNoMatchText.js +30 -0
- package/build/cjs/simple-single-select/__stories__/WithOnBlur.js +23 -0
- package/build/cjs/simple-single-select/__stories__/WithOnFocus.js +23 -0
- package/build/cjs/simple-single-select/__stories__/WithOptionsAndDisabled.js +22 -0
- package/build/cjs/simple-single-select/__stories__/WithOptionsAndLoading.js +34 -0
- package/build/cjs/simple-single-select/__stories__/WithOptionsAndLoadingText.js +35 -0
- package/build/cjs/simple-single-select/__stories__/WithPlaceholder.js +23 -0
- package/build/cjs/simple-single-select/__stories__/WithPlaceholderAndSelection.js +25 -0
- package/build/cjs/simple-single-select/__stories__/WithPrefix.js +22 -0
- package/build/cjs/simple-single-select/__stories__/WithPrefixAndSelection.js +25 -0
- package/build/cjs/simple-single-select/__stories__/WithRTL.js +34 -0
- package/build/cjs/simple-single-select/__stories__/WithSelection.js +24 -0
- package/build/cjs/simple-single-select/__stories__/WithSelectionAndDisabled.js +25 -0
- package/build/cjs/simple-single-select/__stories__/WithoutOptionsAndLoading.js +21 -0
- package/build/cjs/simple-single-select/__stories__/WithoutSelection.js +22 -0
- package/build/cjs/simple-single-select/__stories__/options.js +77 -0
- package/build/cjs/simple-single-select/features/keyboard-interactions.test.e2e.js +441 -0
- package/build/cjs/simple-single-select/features/menu-positioning.test.e2e.js +152 -0
- package/build/cjs/simple-single-select/index.js +19 -0
- package/build/cjs/simple-single-select/is-option-hidden.js +22 -0
- package/build/cjs/simple-single-select/menu/empty.js +26 -0
- package/build/cjs/simple-single-select/menu/filter.js +60 -0
- package/build/cjs/simple-single-select/menu/index.js +12 -0
- package/build/cjs/simple-single-select/menu/loading.js +30 -0
- package/build/cjs/simple-single-select/menu/menu.js +158 -0
- package/build/cjs/simple-single-select/menu/no-match.js +28 -0
- package/build/cjs/simple-single-select/menu/option.js +120 -0
- package/build/cjs/simple-single-select/menu/options-list.js +97 -0
- package/build/cjs/simple-single-select/selected-value/clear-button.js +74 -0
- package/build/cjs/simple-single-select/selected-value/container.js +100 -0
- package/build/cjs/simple-single-select/selected-value/index.js +12 -0
- package/build/cjs/simple-single-select/selected-value/placeholder.js +30 -0
- package/build/cjs/simple-single-select/selected-value/prefix.js +30 -0
- package/build/cjs/simple-single-select/selected-value/selected-value.js +119 -0
- package/build/cjs/simple-single-select/shared-prop-types.js +14 -0
- package/build/cjs/simple-single-select/simple-single-select.e2e.stories.js +156 -0
- package/build/cjs/simple-single-select/simple-single-select.js +319 -0
- package/build/cjs/simple-single-select/simple-single-select.prod.stories.js +228 -0
- package/build/cjs/simple-single-select/simple-single-select.test.js +1106 -0
- package/build/cjs/simple-single-select/use-handle-key-press/index.js +19 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-focus-option.js +24 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +177 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js +106 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-typing.js +81 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-first-option-on-previous-page.js +50 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-first-visible-option.js +30 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-last-option-on-next-page.js +50 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-last-visible-option.js +42 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-page-down.js +45 -0
- package/build/cjs/simple-single-select/use-handle-key-press/use-page-up.js +44 -0
- package/build/cjs/simple-single-select/use-handle-key-press/utils.js +46 -0
- package/build/cjs/simple-single-select-field/index.js +12 -0
- package/build/cjs/simple-single-select-field/simple-single-select-field.js +138 -0
- package/build/cjs/simple-single-select-field/simple-single-select-field.prod.stories.js +188 -0
- package/build/cjs/simple-single-select-field/simple-single-select-field.test.js +133 -0
- package/build/es/index.js +2 -0
- package/build/es/locales/en/translations.json +7 -5
- package/build/es/simple-single-select/__stories__/DefaultPosition.js +29 -0
- package/build/es/simple-single-select/__stories__/Dense.js +13 -0
- package/build/es/simple-single-select/__stories__/Empty.js +11 -0
- package/build/es/simple-single-select/__stories__/EmptyWithEmptyNode.js +19 -0
- package/build/es/simple-single-select/__stories__/EmptyWithEmptyText.js +12 -0
- package/build/es/simple-single-select/__stories__/FlippedPosition.js +28 -0
- package/build/es/simple-single-select/__stories__/InfiniteLoading.js +53 -0
- package/build/es/simple-single-select/__stories__/Loading.js +12 -0
- package/build/es/simple-single-select/__stories__/ShiftedIntoView.js +18 -0
- package/build/es/simple-single-select/__stories__/WithClearButton.js +16 -0
- package/build/es/simple-single-select/__stories__/WithCustomLowMaxHeight.js +13 -0
- package/build/es/simple-single-select/__stories__/WithCustomOptions.js +38 -0
- package/build/es/simple-single-select/__stories__/WithDisabledOption.js +19 -0
- package/build/es/simple-single-select/__stories__/WithFilterField.js +27 -0
- package/build/es/simple-single-select/__stories__/WithInitialFocus.js +29 -0
- package/build/es/simple-single-select/__stories__/WithManyOptions.js +15 -0
- package/build/es/simple-single-select/__stories__/WithNoMatchText.js +21 -0
- package/build/es/simple-single-select/__stories__/WithOnBlur.js +14 -0
- package/build/es/simple-single-select/__stories__/WithOnFocus.js +14 -0
- package/build/es/simple-single-select/__stories__/WithOptionsAndDisabled.js +13 -0
- package/build/es/simple-single-select/__stories__/WithOptionsAndLoading.js +25 -0
- package/build/es/simple-single-select/__stories__/WithOptionsAndLoadingText.js +26 -0
- package/build/es/simple-single-select/__stories__/WithPlaceholder.js +14 -0
- package/build/es/simple-single-select/__stories__/WithPlaceholderAndSelection.js +16 -0
- package/build/es/simple-single-select/__stories__/WithPrefix.js +13 -0
- package/build/es/simple-single-select/__stories__/WithPrefixAndSelection.js +16 -0
- package/build/es/simple-single-select/__stories__/WithRTL.js +25 -0
- package/build/es/simple-single-select/__stories__/WithSelection.js +15 -0
- package/build/es/simple-single-select/__stories__/WithSelectionAndDisabled.js +16 -0
- package/build/es/simple-single-select/__stories__/WithoutOptionsAndLoading.js +12 -0
- package/build/es/simple-single-select/__stories__/WithoutSelection.js +13 -0
- package/build/es/simple-single-select/__stories__/options.js +71 -0
- package/build/es/simple-single-select/features/keyboard-interactions.test.e2e.js +439 -0
- package/build/es/simple-single-select/features/menu-positioning.test.e2e.js +150 -0
- package/build/es/simple-single-select/index.js +2 -0
- package/build/es/simple-single-select/is-option-hidden.js +16 -0
- package/build/es/simple-single-select/menu/empty.js +19 -0
- package/build/es/simple-single-select/menu/filter.js +53 -0
- package/build/es/simple-single-select/menu/index.js +1 -0
- package/build/es/simple-single-select/menu/loading.js +23 -0
- package/build/es/simple-single-select/menu/menu.js +149 -0
- package/build/es/simple-single-select/menu/no-match.js +21 -0
- package/build/es/simple-single-select/menu/option.js +111 -0
- package/build/es/simple-single-select/menu/options-list.js +88 -0
- package/build/es/simple-single-select/selected-value/clear-button.js +68 -0
- package/build/es/simple-single-select/selected-value/container.js +91 -0
- package/build/es/simple-single-select/selected-value/index.js +1 -0
- package/build/es/simple-single-select/selected-value/placeholder.js +23 -0
- package/build/es/simple-single-select/selected-value/prefix.js +23 -0
- package/build/es/simple-single-select/selected-value/selected-value.js +112 -0
- package/build/es/simple-single-select/shared-prop-types.js +7 -0
- package/build/es/simple-single-select/simple-single-select.e2e.stories.js +142 -0
- package/build/es/simple-single-select/simple-single-select.js +310 -0
- package/build/es/simple-single-select/simple-single-select.prod.stories.js +36 -0
- package/build/es/simple-single-select/simple-single-select.test.js +1103 -0
- package/build/es/simple-single-select/use-handle-key-press/index.js +2 -0
- package/build/es/simple-single-select/use-handle-key-press/use-focus-option.js +18 -0
- package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +171 -0
- package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js +100 -0
- package/build/es/simple-single-select/use-handle-key-press/use-handle-typing.js +75 -0
- package/build/es/simple-single-select/use-handle-key-press/use-highlight-first-option-on-previous-page.js +44 -0
- package/build/es/simple-single-select/use-handle-key-press/use-highlight-first-visible-option.js +24 -0
- package/build/es/simple-single-select/use-handle-key-press/use-highlight-last-option-on-next-page.js +44 -0
- package/build/es/simple-single-select/use-handle-key-press/use-highlight-last-visible-option.js +36 -0
- package/build/es/simple-single-select/use-handle-key-press/use-page-down.js +39 -0
- package/build/es/simple-single-select/use-handle-key-press/use-page-up.js +38 -0
- package/build/es/simple-single-select/use-handle-key-press/utils.js +36 -0
- package/build/es/simple-single-select-field/index.js +1 -0
- package/build/es/simple-single-select-field/simple-single-select-field.js +131 -0
- package/build/es/simple-single-select-field/simple-single-select-field.prod.stories.js +172 -0
- package/build/es/simple-single-select-field/simple-single-select-field.test.js +130 -0
- package/package.json +15 -15
- package/types/index.d.ts +184 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "useHandleKeyPressOnCombobox", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _useHandleKeyPressOnCombobox.useHandleKeyPressOnCombobox;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "useHandleKeyPressOnFilterInput", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _useHandleKeyPressOnFilterInput.useHandleKeyPressOnFilterInput;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
var _useHandleKeyPressOnCombobox = require("./use-handle-key-press-on-combobox.js");
|
|
19
|
+
var _useHandleKeyPressOnFilterInput = require("./use-handle-key-press-on-filter-input.js");
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useFocusOption = useFocusOption;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function useFocusOption(findIndexCallback, _ref) {
|
|
9
|
+
let {
|
|
10
|
+
options,
|
|
11
|
+
focussedOptionIndex,
|
|
12
|
+
setFocussedOptionIndex
|
|
13
|
+
} = _ref;
|
|
14
|
+
return (0, _react.useCallback)(() => {
|
|
15
|
+
const nextFocussedIndex = findIndexCallback({
|
|
16
|
+
options,
|
|
17
|
+
activeIndex: focussedOptionIndex
|
|
18
|
+
});
|
|
19
|
+
if (nextFocussedIndex === -1) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
setFocussedOptionIndex(nextFocussedIndex);
|
|
23
|
+
}, [findIndexCallback, options, focussedOptionIndex, setFocussedOptionIndex]);
|
|
24
|
+
}
|
package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHandleKeyPressOnCombobox = useHandleKeyPressOnCombobox;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _useFocusOption = require("./use-focus-option.js");
|
|
9
|
+
var _useHandleTyping = require("./use-handle-typing.js");
|
|
10
|
+
var _usePageDown = require("./use-page-down.js");
|
|
11
|
+
var _usePageUp = require("./use-page-up.js");
|
|
12
|
+
var _utils = require("./utils.js");
|
|
13
|
+
function useSelectOption(findIndexCallback, _ref) {
|
|
14
|
+
let {
|
|
15
|
+
options,
|
|
16
|
+
onChange,
|
|
17
|
+
value
|
|
18
|
+
} = _ref;
|
|
19
|
+
return (0, _react.useCallback)(() => {
|
|
20
|
+
const currentOptionIndex = options.findIndex(option => option.value === value);
|
|
21
|
+
const nextSelectedOptionIndex = findIndexCallback({
|
|
22
|
+
options,
|
|
23
|
+
activeIndex: currentOptionIndex
|
|
24
|
+
});
|
|
25
|
+
if (nextSelectedOptionIndex === -1) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const nextOption = options[nextSelectedOptionIndex];
|
|
29
|
+
onChange({
|
|
30
|
+
label: nextOption.label,
|
|
31
|
+
value: nextOption.value
|
|
32
|
+
});
|
|
33
|
+
}, [findIndexCallback, options, onChange, value]);
|
|
34
|
+
}
|
|
35
|
+
function useHandleKeyPressOnCombobox(_ref2) {
|
|
36
|
+
let {
|
|
37
|
+
value,
|
|
38
|
+
disabled,
|
|
39
|
+
expanded,
|
|
40
|
+
loading,
|
|
41
|
+
options,
|
|
42
|
+
openMenu,
|
|
43
|
+
closeMenu,
|
|
44
|
+
listBoxRef,
|
|
45
|
+
focussedOptionIndex,
|
|
46
|
+
setFocussedOptionIndex,
|
|
47
|
+
selectFocussedOption,
|
|
48
|
+
onChange
|
|
49
|
+
} = _ref2;
|
|
50
|
+
const {
|
|
51
|
+
onTyping,
|
|
52
|
+
typing
|
|
53
|
+
} = (0, _useHandleTyping.useHandleTyping)({
|
|
54
|
+
expanded,
|
|
55
|
+
options,
|
|
56
|
+
setFocussedOptionIndex,
|
|
57
|
+
onChange
|
|
58
|
+
});
|
|
59
|
+
const pageDown = (0, _usePageDown.usePageDown)({
|
|
60
|
+
options,
|
|
61
|
+
focussedOptionIndex,
|
|
62
|
+
setFocussedOptionIndex,
|
|
63
|
+
listBoxRef
|
|
64
|
+
});
|
|
65
|
+
const pageUp = (0, _usePageUp.usePageUp)({
|
|
66
|
+
options,
|
|
67
|
+
listBoxRef,
|
|
68
|
+
focussedOptionIndex,
|
|
69
|
+
setFocussedOptionIndex
|
|
70
|
+
});
|
|
71
|
+
const selectNextOption = useSelectOption(_utils.findNextOptionIndex, {
|
|
72
|
+
options,
|
|
73
|
+
onChange,
|
|
74
|
+
value
|
|
75
|
+
});
|
|
76
|
+
const selectPrevOption = useSelectOption(_utils.findPrevOptionIndex, {
|
|
77
|
+
options,
|
|
78
|
+
onChange,
|
|
79
|
+
value
|
|
80
|
+
});
|
|
81
|
+
const focusNextOption = (0, _useFocusOption.useFocusOption)(_utils.findNextOptionIndex, {
|
|
82
|
+
options,
|
|
83
|
+
focussedOptionIndex,
|
|
84
|
+
setFocussedOptionIndex
|
|
85
|
+
});
|
|
86
|
+
const focusPrevOption = (0, _useFocusOption.useFocusOption)(_utils.findPrevOptionIndex, {
|
|
87
|
+
options,
|
|
88
|
+
focussedOptionIndex,
|
|
89
|
+
setFocussedOptionIndex
|
|
90
|
+
});
|
|
91
|
+
const focusFirstOption = (0, _useFocusOption.useFocusOption)(_utils.findFirstOptionIndex, {
|
|
92
|
+
options,
|
|
93
|
+
focussedOptionIndex,
|
|
94
|
+
setFocussedOptionIndex
|
|
95
|
+
});
|
|
96
|
+
const focusLastOption = (0, _useFocusOption.useFocusOption)(_utils.findLastOptionIndex, {
|
|
97
|
+
options,
|
|
98
|
+
focussedOptionIndex,
|
|
99
|
+
setFocussedOptionIndex
|
|
100
|
+
});
|
|
101
|
+
const handleKeyPress = (0, _react.useCallback)(_ref3 => {
|
|
102
|
+
let {
|
|
103
|
+
key,
|
|
104
|
+
altKey,
|
|
105
|
+
ctrlKey,
|
|
106
|
+
metaKey
|
|
107
|
+
} = _ref3;
|
|
108
|
+
if (disabled || loading) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* The menu won't be an ancestor / sibling of the combobox,
|
|
114
|
+
* so when pressing tab, it's highly unlikely that any element
|
|
115
|
+
* in the menu would receive focus (happens only in storybook,
|
|
116
|
+
* where there's no other focussable element).
|
|
117
|
+
*
|
|
118
|
+
* Assistive technology will know about the menu as the combobox
|
|
119
|
+
* has the appropriate aria attributes that will point to the
|
|
120
|
+
* correct HTML elements.
|
|
121
|
+
*/
|
|
122
|
+
if (expanded && key === 'Tab') {
|
|
123
|
+
closeMenu();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (expanded && (key === 'Escape' || key === 'Enter' || key === ' ' && !typing || key === 'ArrowUp' && altKey || key === 'ArrowDown' && altKey)) {
|
|
127
|
+
if (value !== options[focussedOptionIndex].value) {
|
|
128
|
+
selectFocussedOption();
|
|
129
|
+
}
|
|
130
|
+
closeMenu();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!expanded && (key === ' ' && !typing || key === 'Enter' || key === 'ArrowUp' && altKey || key === 'ArrowDown' && altKey)) {
|
|
134
|
+
openMenu();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (key === 'ArrowDown' && !expanded) {
|
|
138
|
+
selectNextOption();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (key === 'ArrowDown') {
|
|
142
|
+
focusNextOption();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (key === 'ArrowUp' && !expanded) {
|
|
146
|
+
selectPrevOption();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (key === 'ArrowUp') {
|
|
150
|
+
focusPrevOption();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (key === 'Home') {
|
|
154
|
+
focusFirstOption();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (key === 'End') {
|
|
158
|
+
focusLastOption();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (key === 'Backspace' || key === 'Clear' || key.length === 1 && key !== ' ' && !altKey && !ctrlKey && !metaKey || key === ' ' && typing) {
|
|
162
|
+
onTyping(key);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (expanded && key === 'PageUp') {
|
|
166
|
+
pageUp();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (expanded && key === 'PageDown') {
|
|
170
|
+
pageDown();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Do nothing
|
|
175
|
+
}, [closeMenu, disabled, expanded, loading, openMenu, options, value, typing, focussedOptionIndex, selectFocussedOption, selectNextOption, selectPrevOption, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp, onTyping]);
|
|
176
|
+
return handleKeyPress;
|
|
177
|
+
}
|
package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHandleKeyPressOnFilterInput = useHandleKeyPressOnFilterInput;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _useFocusOption = require("./use-focus-option.js");
|
|
9
|
+
var _usePageDown = require("./use-page-down.js");
|
|
10
|
+
var _usePageUp = require("./use-page-up.js");
|
|
11
|
+
var _utils = require("./utils.js");
|
|
12
|
+
function useHandleKeyPressOnFilterInput(_ref) {
|
|
13
|
+
let {
|
|
14
|
+
value,
|
|
15
|
+
options,
|
|
16
|
+
loading,
|
|
17
|
+
closeMenu,
|
|
18
|
+
listBoxRef,
|
|
19
|
+
focusComboBox,
|
|
20
|
+
focussedOptionIndex,
|
|
21
|
+
setFocussedOptionIndex,
|
|
22
|
+
selectFocussedOption
|
|
23
|
+
} = _ref;
|
|
24
|
+
const pageDown = (0, _usePageDown.usePageDown)({
|
|
25
|
+
options,
|
|
26
|
+
focussedOptionIndex,
|
|
27
|
+
setFocussedOptionIndex,
|
|
28
|
+
listBoxRef
|
|
29
|
+
});
|
|
30
|
+
const pageUp = (0, _usePageUp.usePageUp)({
|
|
31
|
+
options,
|
|
32
|
+
listBoxRef,
|
|
33
|
+
focussedOptionIndex,
|
|
34
|
+
setFocussedOptionIndex
|
|
35
|
+
});
|
|
36
|
+
const focusNextOption = (0, _useFocusOption.useFocusOption)(_utils.findNextOptionIndex, {
|
|
37
|
+
options,
|
|
38
|
+
focussedOptionIndex,
|
|
39
|
+
setFocussedOptionIndex
|
|
40
|
+
});
|
|
41
|
+
const focusPrevOption = (0, _useFocusOption.useFocusOption)(_utils.findPrevOptionIndex, {
|
|
42
|
+
options,
|
|
43
|
+
focussedOptionIndex,
|
|
44
|
+
setFocussedOptionIndex
|
|
45
|
+
});
|
|
46
|
+
const focusFirstOption = (0, _useFocusOption.useFocusOption)(_utils.findFirstOptionIndex, {
|
|
47
|
+
options,
|
|
48
|
+
focussedOptionIndex,
|
|
49
|
+
setFocussedOptionIndex
|
|
50
|
+
});
|
|
51
|
+
const focusLastOption = (0, _useFocusOption.useFocusOption)(_utils.findLastOptionIndex, {
|
|
52
|
+
options,
|
|
53
|
+
focussedOptionIndex,
|
|
54
|
+
setFocussedOptionIndex
|
|
55
|
+
});
|
|
56
|
+
const handleKeyPress = (0, _react.useCallback)(e => {
|
|
57
|
+
if (loading) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const {
|
|
61
|
+
key,
|
|
62
|
+
altKey
|
|
63
|
+
} = e;
|
|
64
|
+
if (key === 'Escape' || key === 'Enter' || key === 'ArrowUp' && altKey || key === 'ArrowDown' && altKey) {
|
|
65
|
+
if (value !== options[focussedOptionIndex].value) {
|
|
66
|
+
selectFocussedOption();
|
|
67
|
+
}
|
|
68
|
+
closeMenu();
|
|
69
|
+
|
|
70
|
+
// As the filter is being focused, we want to move focus back to the combobox
|
|
71
|
+
focusComboBox();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (key === 'ArrowDown') {
|
|
75
|
+
e.preventDefault(); // Disable moving cursor to end
|
|
76
|
+
focusNextOption();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (key === 'ArrowUp') {
|
|
80
|
+
e.preventDefault(); // Disable moving cursor to start
|
|
81
|
+
focusPrevOption();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (key === 'Home') {
|
|
85
|
+
e.preventDefault(); // Disable moving cursor to start
|
|
86
|
+
focusFirstOption();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (key === 'End') {
|
|
90
|
+
e.preventDefault(); // Disable moving cursor to end
|
|
91
|
+
focusLastOption();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (key === 'PageUp') {
|
|
95
|
+
pageUp();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (key === 'PageDown') {
|
|
99
|
+
pageDown();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Do nothing
|
|
104
|
+
}, [closeMenu, options, value, loading, focussedOptionIndex, selectFocussedOption, focusComboBox, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp]);
|
|
105
|
+
return handleKeyPress;
|
|
106
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHandleTyping = useHandleTyping;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
const TYPING_DEBOUNCE_TIME = 300; // ms
|
|
9
|
+
|
|
10
|
+
function useHandleTyping(_ref) {
|
|
11
|
+
let {
|
|
12
|
+
expanded,
|
|
13
|
+
options,
|
|
14
|
+
setFocussedOptionIndex,
|
|
15
|
+
onChange
|
|
16
|
+
} = _ref;
|
|
17
|
+
const [value, setValue] = (0, _react.useState)('');
|
|
18
|
+
const [typing, setTyping] = (0, _react.useState)(false);
|
|
19
|
+
|
|
20
|
+
// This will reset the typed value after a given time
|
|
21
|
+
const timeoutRef = (0, _react.useRef)();
|
|
22
|
+
(0, _react.useEffect)(() => {
|
|
23
|
+
if (timeoutRef.current) {
|
|
24
|
+
clearTimeout(timeoutRef.current);
|
|
25
|
+
timeoutRef.current = null;
|
|
26
|
+
}
|
|
27
|
+
if (value) {
|
|
28
|
+
timeoutRef.current = setTimeout(() => {
|
|
29
|
+
setValue('');
|
|
30
|
+
setTyping(false);
|
|
31
|
+
}, TYPING_DEBOUNCE_TIME);
|
|
32
|
+
} else {
|
|
33
|
+
setTyping(false);
|
|
34
|
+
}
|
|
35
|
+
}, [
|
|
36
|
+
// adding value to the dependencies array so that the hooks runs every time the value changes
|
|
37
|
+
value]);
|
|
38
|
+
|
|
39
|
+
// This will focus the first option with a label starting with the typed sequence
|
|
40
|
+
const prevValueRef = (0, _react.useRef)();
|
|
41
|
+
(0, _react.useEffect)(() => {
|
|
42
|
+
if (value && value !== prevValueRef.current) {
|
|
43
|
+
// We only want to do this when the value changed
|
|
44
|
+
prevValueRef.current = value;
|
|
45
|
+
const optionIndex = options.findIndex(_ref2 => {
|
|
46
|
+
let {
|
|
47
|
+
disabled,
|
|
48
|
+
label
|
|
49
|
+
} = _ref2;
|
|
50
|
+
return !disabled && label.toLowerCase().startsWith(value.toLowerCase());
|
|
51
|
+
});
|
|
52
|
+
if (optionIndex !== -1) {
|
|
53
|
+
if (expanded) {
|
|
54
|
+
setFocussedOptionIndex(optionIndex);
|
|
55
|
+
} else {
|
|
56
|
+
const nextSelectedOption = options[optionIndex];
|
|
57
|
+
onChange({
|
|
58
|
+
label: nextSelectedOption.label,
|
|
59
|
+
value: nextSelectedOption.value
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, [value, options, setFocussedOptionIndex, expanded, onChange]);
|
|
65
|
+
const onTyping = (0, _react.useCallback)(key => {
|
|
66
|
+
setTyping(true);
|
|
67
|
+
if (key === 'Backspace') {
|
|
68
|
+
setValue(prevValue => prevValue.slice(0, -1));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (key === 'Clear') {
|
|
72
|
+
setValue('');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setValue(prevValue => `${prevValue}${key}`);
|
|
76
|
+
}, []);
|
|
77
|
+
return {
|
|
78
|
+
onTyping,
|
|
79
|
+
typing
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHighlightFirstOptionOnPreviousPage = useHighlightFirstOptionOnPreviousPage;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function useHighlightFirstOptionOnPreviousPage(_ref) {
|
|
9
|
+
let {
|
|
10
|
+
options,
|
|
11
|
+
focussedOptionIndex,
|
|
12
|
+
setFocussedOptionIndex,
|
|
13
|
+
listBoxRef
|
|
14
|
+
} = _ref;
|
|
15
|
+
return (0, _react.useCallback)(() => {
|
|
16
|
+
const listBoxParent = listBoxRef.current.parentNode;
|
|
17
|
+
const optionElements = Array.from(listBoxRef.current.childNodes);
|
|
18
|
+
const visibleOptionsAmount = Math.floor(listBoxParent.offsetHeight / optionElements[0].offsetHeight);
|
|
19
|
+
const nextTopOptionIndex = Math.max(0, focussedOptionIndex - visibleOptionsAmount);
|
|
20
|
+
|
|
21
|
+
// If there's no next option and we already have the last option in the list highlighted
|
|
22
|
+
if (!options[nextTopOptionIndex]) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!options[nextTopOptionIndex].disabled) {
|
|
26
|
+
const nextTopOption = optionElements[nextTopOptionIndex];
|
|
27
|
+
const scrollPosition = nextTopOption.offsetTop;
|
|
28
|
+
listBoxParent.scrollTop = scrollPosition;
|
|
29
|
+
setFocussedOptionIndex(nextTopOptionIndex);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const lowerEnabledOptionIndex = options.slice(0, nextTopOptionIndex).findLastIndex(option => !option.disabled);
|
|
33
|
+
if (lowerEnabledOptionIndex !== -1) {
|
|
34
|
+
const lowerEnabledOption = optionElements[lowerEnabledOptionIndex];
|
|
35
|
+
const lowerScrollPosition = lowerEnabledOption.offsetTop;
|
|
36
|
+
listBoxParent.scrollTop = lowerScrollPosition;
|
|
37
|
+
setFocussedOptionIndex(lowerEnabledOptionIndex);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const inbetweenEnabledOptionIndex = nextTopOptionIndex + options.slice(nextTopOptionIndex, focussedOptionIndex).findIndex(option => !option.disabled);
|
|
41
|
+
if (inbetweenEnabledOptionIndex === -1) {
|
|
42
|
+
// We're already on the first enabled option
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const inbetweenTopOption = optionElements[inbetweenEnabledOptionIndex];
|
|
46
|
+
const scrollPosition = inbetweenTopOption.offsetTop;
|
|
47
|
+
listBoxParent.scrollTop = scrollPosition;
|
|
48
|
+
setFocussedOptionIndex(inbetweenEnabledOptionIndex);
|
|
49
|
+
}, [options, focussedOptionIndex, setFocussedOptionIndex, listBoxRef]);
|
|
50
|
+
}
|
package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-first-visible-option.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHighlightFirstVisibleOption = useHighlightFirstVisibleOption;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function useHighlightFirstVisibleOption(_ref) {
|
|
9
|
+
let {
|
|
10
|
+
options,
|
|
11
|
+
focussedOptionIndex,
|
|
12
|
+
setFocussedOptionIndex
|
|
13
|
+
} = _ref;
|
|
14
|
+
return (0, _react.useCallback)(lowestVisibleIndex => {
|
|
15
|
+
if (!options[lowestVisibleIndex].disabled) {
|
|
16
|
+
setFocussedOptionIndex(lowestVisibleIndex);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const previousEnabledOptionIndex = options.slice(0, lowestVisibleIndex).findLastIndex(option => !option.disabled);
|
|
20
|
+
if (previousEnabledOptionIndex !== -1) {
|
|
21
|
+
setFocussedOptionIndex(previousEnabledOptionIndex);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const nextEnabledOptionIndex = lowestVisibleIndex + options.slice(lowestVisibleIndex, focussedOptionIndex).findIndex(option => !option.disabled);
|
|
25
|
+
if (nextEnabledOptionIndex !== -1) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
setFocussedOptionIndex(nextEnabledOptionIndex);
|
|
29
|
+
}, [options, focussedOptionIndex, setFocussedOptionIndex]);
|
|
30
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHighlightLastOptionOnNextPage = useHighlightLastOptionOnNextPage;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function useHighlightLastOptionOnNextPage(_ref) {
|
|
9
|
+
let {
|
|
10
|
+
options,
|
|
11
|
+
focussedOptionIndex,
|
|
12
|
+
setFocussedOptionIndex,
|
|
13
|
+
listBoxRef
|
|
14
|
+
} = _ref;
|
|
15
|
+
return (0, _react.useCallback)(() => {
|
|
16
|
+
const listBoxParent = listBoxRef.current.parentNode;
|
|
17
|
+
const optionElements = Array.from(listBoxRef.current.childNodes);
|
|
18
|
+
const visibleOptionsAmount = Math.floor(listBoxParent.offsetHeight / optionElements[0].offsetHeight);
|
|
19
|
+
const nextHighlightedOptionIndex = Math.min(options.length - 1, focussedOptionIndex + visibleOptionsAmount);
|
|
20
|
+
|
|
21
|
+
// If there's no next option and we already have the last option in the list highlighted
|
|
22
|
+
if (!options[nextHighlightedOptionIndex]) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!options[nextHighlightedOptionIndex].disabled) {
|
|
26
|
+
// This will be the first option in the list
|
|
27
|
+
const {
|
|
28
|
+
offsetTop: scrollPosition
|
|
29
|
+
} = optionElements[nextHighlightedOptionIndex - visibleOptionsAmount + 1];
|
|
30
|
+
listBoxParent.scrollTop = scrollPosition;
|
|
31
|
+
setFocussedOptionIndex(nextHighlightedOptionIndex);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const followingEnabledOptionIndex = nextHighlightedOptionIndex + options.slice(nextHighlightedOptionIndex).findIndex(option => !option.disabled);
|
|
35
|
+
|
|
36
|
+
// There is no enabled option after the disabled option that's at the end of the next page
|
|
37
|
+
// So we stay where we are
|
|
38
|
+
if (followingEnabledOptionIndex === -1) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// There is an enabled option after the disabled option that's at the end of the next page
|
|
43
|
+
// So that'll be the new highlighted option and the bottom of the next displayed page
|
|
44
|
+
const {
|
|
45
|
+
offsetTop: adjustedScrollPosition
|
|
46
|
+
} = optionElements[followingEnabledOptionIndex - visibleOptionsAmount + 1];
|
|
47
|
+
listBoxParent.scrollTop = adjustedScrollPosition;
|
|
48
|
+
setFocussedOptionIndex(followingEnabledOptionIndex);
|
|
49
|
+
}, [options, focussedOptionIndex, setFocussedOptionIndex, listBoxRef]);
|
|
50
|
+
}
|
package/build/cjs/simple-single-select/use-handle-key-press/use-highlight-last-visible-option.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useHighlightLastVisibleOption = useHighlightLastVisibleOption;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function useHighlightLastVisibleOption(_ref) {
|
|
9
|
+
let {
|
|
10
|
+
options,
|
|
11
|
+
focussedOptionIndex,
|
|
12
|
+
setFocussedOptionIndex
|
|
13
|
+
} = _ref;
|
|
14
|
+
return (0, _react.useCallback)(highestVisibleIndex => {
|
|
15
|
+
if (!options[highestVisibleIndex].disabled) {
|
|
16
|
+
setFocussedOptionIndex(highestVisibleIndex);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Last option on page is disabled, find next option that's not disabled
|
|
21
|
+
const followingEnabledOptionIndex = options.slice(highestVisibleIndex).findIndex(option => !option.disabled);
|
|
22
|
+
if (followingEnabledOptionIndex >= 0) {
|
|
23
|
+
// We need to add the highest visible index because the index is lower due to slicing the array
|
|
24
|
+
setFocussedOptionIndex(followingEnabledOptionIndex + highestVisibleIndex);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// No following enabled option, trying to find the closest previous sibling of the last option on the current page
|
|
29
|
+
const closestToEndOfPageEnabledOptionIndex = options.slice(
|
|
30
|
+
// We don't include the currently highlighted option
|
|
31
|
+
focussedOptionIndex + 1, highestVisibleIndex).findLastIndex(option => !option.disabled);
|
|
32
|
+
if (closestToEndOfPageEnabledOptionIndex >= 0) {
|
|
33
|
+
setFocussedOptionIndex(closestToEndOfPageEnabledOptionIndex +
|
|
34
|
+
// We need to add the focused index and 1 because the index is lower due to slicing the array
|
|
35
|
+
focussedOptionIndex + 1);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// The currently highlighted option is the last enabled option
|
|
40
|
+
return;
|
|
41
|
+
}, [options, focussedOptionIndex, setFocussedOptionIndex]);
|
|
42
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.usePageDown = usePageDown;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _isOptionHidden = require("../is-option-hidden.js");
|
|
9
|
+
var _useHighlightLastOptionOnNextPage = require("./use-highlight-last-option-on-next-page.js");
|
|
10
|
+
var _useHighlightLastVisibleOption = require("./use-highlight-last-visible-option.js");
|
|
11
|
+
function usePageDown(_ref) {
|
|
12
|
+
let {
|
|
13
|
+
options,
|
|
14
|
+
focussedOptionIndex,
|
|
15
|
+
setFocussedOptionIndex,
|
|
16
|
+
listBoxRef
|
|
17
|
+
} = _ref;
|
|
18
|
+
const highlightLastVisibleOption = (0, _useHighlightLastVisibleOption.useHighlightLastVisibleOption)({
|
|
19
|
+
options,
|
|
20
|
+
focussedOptionIndex,
|
|
21
|
+
setFocussedOptionIndex
|
|
22
|
+
});
|
|
23
|
+
const highlightLastOptionOnNextPage = (0, _useHighlightLastOptionOnNextPage.useHighlightLastOptionOnNextPage)({
|
|
24
|
+
options,
|
|
25
|
+
focussedOptionIndex,
|
|
26
|
+
setFocussedOptionIndex,
|
|
27
|
+
listBoxRef
|
|
28
|
+
});
|
|
29
|
+
return (0, _react.useCallback)(() => {
|
|
30
|
+
const listBoxParent = listBoxRef.current.parentNode;
|
|
31
|
+
const options = Array.from(listBoxRef.current.childNodes);
|
|
32
|
+
const highestVisibleIndex = options.findLastIndex(option => !(0, _isOptionHidden.isOptionHidden)(option, listBoxParent));
|
|
33
|
+
if (highestVisibleIndex > focussedOptionIndex) {
|
|
34
|
+
highlightLastVisibleOption(highestVisibleIndex);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (highestVisibleIndex > -1) {
|
|
38
|
+
highlightLastOptionOnNextPage();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// No visible option (e.g. when menu is empty)
|
|
43
|
+
return;
|
|
44
|
+
}, [focussedOptionIndex, listBoxRef, highlightLastVisibleOption, highlightLastOptionOnNextPage]);
|
|
45
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.usePageUp = usePageUp;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _isOptionHidden = require("../is-option-hidden.js");
|
|
9
|
+
var _useHighlightFirstOptionOnPreviousPage = require("./use-highlight-first-option-on-previous-page.js");
|
|
10
|
+
var _useHighlightFirstVisibleOption = require("./use-highlight-first-visible-option.js");
|
|
11
|
+
function usePageUp(_ref) {
|
|
12
|
+
let {
|
|
13
|
+
options,
|
|
14
|
+
listBoxRef,
|
|
15
|
+
focussedOptionIndex,
|
|
16
|
+
setFocussedOptionIndex
|
|
17
|
+
} = _ref;
|
|
18
|
+
const highlightFirstVisibleOption = (0, _useHighlightFirstVisibleOption.useHighlightFirstVisibleOption)({
|
|
19
|
+
options,
|
|
20
|
+
focussedOptionIndex,
|
|
21
|
+
setFocussedOptionIndex
|
|
22
|
+
});
|
|
23
|
+
const highlightFirstOptionOnPreviousPage = (0, _useHighlightFirstOptionOnPreviousPage.useHighlightFirstOptionOnPreviousPage)({
|
|
24
|
+
options,
|
|
25
|
+
focussedOptionIndex,
|
|
26
|
+
setFocussedOptionIndex,
|
|
27
|
+
listBoxRef
|
|
28
|
+
});
|
|
29
|
+
return (0, _react.useCallback)(() => {
|
|
30
|
+
const listBoxParent = listBoxRef.current.parentNode;
|
|
31
|
+
const optionElements = Array.from(listBoxRef.current.childNodes);
|
|
32
|
+
const lowestVisibleIndex = optionElements.findIndex(optionElement => !(0, _isOptionHidden.isOptionHidden)(optionElement, listBoxParent));
|
|
33
|
+
|
|
34
|
+
// No visible option (e.g. when menu is empty)
|
|
35
|
+
if (lowestVisibleIndex === -1) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (lowestVisibleIndex < focussedOptionIndex) {
|
|
39
|
+
highlightFirstVisibleOption(lowestVisibleIndex);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
highlightFirstOptionOnPreviousPage();
|
|
43
|
+
}, [focussedOptionIndex, listBoxRef, highlightFirstOptionOnPreviousPage, highlightFirstVisibleOption]);
|
|
44
|
+
}
|