Skip to content

Commit f065503

Browse files
committed
Fixes 11053: focus event causing jumpy scroll effect
1 parent aef0e84 commit f065503

File tree

5 files changed

+12
-20
lines changed

5 files changed

+12
-20
lines changed

packages/react-core/src/components/Dropdown/Dropdown.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,18 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
114114
) {
115115
if (onOpenChangeKeys.includes(event.key)) {
116116
onOpenChange(false);
117-
toggleRef.current?.focus();
117+
toggleRef.current?.focus({preventScroll:true});
118118
}
119119
}
120120
};
121121

122122
const handleClick = (event: MouseEvent) => {
123123
// toggle was opened, focus on first menu item
124124
if (isOpen && shouldFocusFirstItemOnOpen && toggleRef.current?.contains(event.target as Node)) {
125-
setTimeout(() => {
126125
const firstElement = menuRef?.current?.querySelector(
127126
'li button:not(:disabled),li input:not(:disabled),li a:not([aria-disabled="true"])'
128127
);
129-
firstElement && (firstElement as HTMLElement).focus();
130-
}, 10);
128+
firstElement && (firstElement as HTMLElement).focus({preventScroll:true});
131129
}
132130

133131
// If the event is not on the toggle and onOpenChange callback is provided, close the menu
@@ -155,7 +153,7 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
155153
ref={menuRef}
156154
onSelect={(event, value) => {
157155
onSelect && onSelect(event, value);
158-
shouldFocusToggleOnSelect && toggleRef.current.focus();
156+
shouldFocusToggleOnSelect && toggleRef.current?.focus();
159157
}}
160158
isPlain={isPlain}
161159
isScrollable={scrollable}

packages/react-core/src/components/Menu/MenuContainer.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,18 @@ export const MenuContainer: React.FunctionComponent<MenuContainerProps> = ({
6363
) {
6464
if (onOpenChangeKeys.includes(event.key)) {
6565
onOpenChange(false);
66-
toggleRef.current?.focus();
66+
toggleRef.current?.focus({preventScroll:true});
6767
}
6868
}
6969
};
7070

7171
const handleClick = (event: MouseEvent) => {
7272
// toggle was opened, focus on first menu item
7373
if (isOpen && toggleRef.current?.contains(event.target as Node)) {
74-
setTimeout(() => {
7574
const firstElement = menuRef?.current?.querySelector(
7675
'li button:not(:disabled),li input:not(:disabled),li a:not([aria-disabled="true"])'
7776
);
78-
firstElement && (firstElement as HTMLElement).focus();
79-
}, 0);
77+
firstElement && (firstElement as HTMLElement).focus({preventScroll:true});
8078
}
8179

8280
// If the event is not on the toggle and onOpenChange callback is provided, close the menu

packages/react-core/src/components/Pagination/PaginationOptionsMenu.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,16 @@ export const PaginationOptionsMenu: React.FunctionComponent<PaginationOptionsMen
123123
) {
124124
if (event.key === 'Escape' || event.key === 'Tab') {
125125
setIsOpen(false);
126-
toggleRef.current?.focus();
126+
toggleRef.current?.focus({preventScroll:true});
127127
}
128128
}
129129
};
130130

131131
const handleClick = (event: MouseEvent) => {
132132
// Focus the first non-disabled menu item on toggle 'click'
133133
if (isOpen && toggleRef.current?.contains(event.target as Node)) {
134-
setTimeout(() => {
135134
const firstElement = menuRef?.current?.querySelector('li button:not(:disabled)');
136-
firstElement && (firstElement as HTMLElement).focus();
137-
}, 0);
135+
firstElement && (firstElement as HTMLElement).focus({preventScroll:true});
138136
}
139137

140138
// If the event is not on the toggle, close the menu

packages/react-core/src/components/Select/Select.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,16 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
121121
if (onOpenChangeKeys.includes(event.key)) {
122122
event.preventDefault();
123123
onOpenChange(false);
124-
toggleRef.current?.focus();
124+
toggleRef.current?.focus({preventScroll:true});
125125
}
126126
}
127127
};
128128

129129
const handleClick = (event: MouseEvent) => {
130130
// toggle was opened, focus on first menu item
131131
if (isOpen && shouldFocusFirstItemOnOpen && toggleRef.current?.contains(event.target as Node)) {
132-
setTimeout(() => {
133132
const firstElement = menuRef?.current?.querySelector('li button:not(:disabled),li input:not(:disabled)');
134-
firstElement && (firstElement as HTMLElement).focus();
135-
}, 10);
133+
firstElement && (firstElement as HTMLElement).focus({preventScroll:true});
136134
}
137135

138136
// If the event is not on the toggle and onOpenChange callback is provided, close the menu

packages/react-core/src/components/Tabs/OverflowTab.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ export const OverflowTab: React.FunctionComponent<OverflowTabProps> = ({
7575

7676
const toggleMenu = () => {
7777
setIsExpanded((prevIsExpanded) => !prevIsExpanded);
78-
setTimeout(() => {
78+
7979
if (menuRef?.current) {
8080
const firstElement = menuRef.current.querySelector('li > button,input:not(:disabled)');
81-
firstElement && (firstElement as HTMLElement).focus();
81+
firstElement && (firstElement as HTMLElement).focus({preventScroll:true});
8282
}
83-
}, 0);
83+
8484
};
8585

8686
const overflowTab = (

0 commit comments

Comments
 (0)