Skip to content

Commit

Permalink
feat(Dropdown): allowed preventing autofocus v6 (#10708)
Browse files Browse the repository at this point in the history
  • Loading branch information
thatblindgeye authored Jul 11, 2024
1 parent c2d71d0 commit 9fe5e5a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 11,302 deletions.
5 changes: 4 additions & 1 deletion packages/react-core/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export interface DropdownProps extends MenuProps, OUIAProps {
menuHeight?: string;
/** Maximum height of dropdown menu */
maxMenuHeight?: string;
/** @beta Flag indicating the first menu item should be focused after opening the dropdown. */
shouldFocusFirstItemOnOpen?: boolean;
}

const DropdownBase: React.FunctionComponent<DropdownProps> = ({
Expand All @@ -89,6 +91,7 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
onOpenChangeKeys = ['Escape', 'Tab'],
menuHeight,
maxMenuHeight,
shouldFocusFirstItemOnOpen = true,
...props
}: DropdownProps) => {
const localMenuRef = React.useRef<HTMLDivElement>();
Expand Down Expand Up @@ -118,7 +121,7 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({

const handleClick = (event: MouseEvent) => {
// toggle was opened, focus on first menu item
if (isOpen && toggleRef.current?.contains(event.target as Node)) {
if (isOpen && shouldFocusFirstItemOnOpen && toggleRef.current?.contains(event.target as Node)) {
setTimeout(() => {
const firstElement = menuRef?.current?.querySelector(
'li button:not(:disabled),li input:not(:disabled),li a:not([aria-disabled="true"])'
Expand Down
11 changes: 11 additions & 0 deletions packages/react-integration/cypress/integration/dropdown.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,15 @@ describe('Dropdown demo test', () => {
pressing enter or space key on a button calls a click event internally
so testing for a button click should be sufficient
*/

it('Autofocuses first item on click by default', () => {
cy.get('[data-cy="toggle"]').click();
cy.get('#first-item').should('be.focused');
cy.get('[data-cy="toggle"]').trigger('keydown', { key: 'Escape' });
});
it('Does not autofocus first item on click when shouldFocusFirstItemOnOpen is false', () => {
cy.get('[data-cy="no-autofocus-toggle"]').click();
cy.get('#first-item').should('not.be.focused');
cy.get('[data-cy="toggle"]').trigger('keydown', { key: 'Escape' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Dropdown, DropdownList, DropdownItem, Divider, MenuToggle } from '@patt

const dropDownItems = (
<DropdownList>
<DropdownItem value={0} key="link">
<DropdownItem id="first-item" value={0} key="link">
Link
</DropdownItem>
<DropdownItem
Expand Down Expand Up @@ -36,28 +36,55 @@ const dropDownItems = (

export const DropdownDemo: React.FunctionComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);
const [isNoAutofocusOpen, setIsNoAutofocusOpen] = React.useState(false);

const onToggleClick = () => {
setIsOpen(!isOpen);
};
const onNoAutofocusToggleClick = () => {
setIsOpen(!isOpen);
};

const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined) => {
setIsOpen(false);
};
const onNoAutofocusSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined) => {
setIsOpen(false);
};

return (
<Dropdown
isOpen={isOpen}
onOpenChange={(isOpen) => setIsOpen(isOpen)}
onSelect={onSelect}
toggle={(toggleRef) => (
<MenuToggle data-cy="toggle" onClick={onToggleClick} isExpanded={isOpen} ref={toggleRef}>
Dropdown
</MenuToggle>
)}
>
{dropDownItems}
</Dropdown>
<>
<Dropdown
isOpen={isOpen}
onOpenChange={(isOpen) => setIsOpen(isOpen)}
onSelect={onSelect}
toggle={(toggleRef) => (
<MenuToggle data-cy="toggle" onClick={onToggleClick} isExpanded={isOpen} ref={toggleRef}>
Dropdown
</MenuToggle>
)}
>
{dropDownItems}
</Dropdown>
<Dropdown
isOpen={isNoAutofocusOpen}
shouldFocusFirstItemOnOpen={false}
onOpenChange={(isOpen) => setIsNoAutofocusOpen(isOpen)}
onSelect={onNoAutofocusSelect}
toggle={(toggleRef) => (
<MenuToggle
data-cy="no-autofocus-toggle"
onClick={onNoAutofocusToggleClick}
isExpanded={isNoAutofocusOpen}
ref={toggleRef}
>
Dropdown
</MenuToggle>
)}
>
{dropDownItems}
</Dropdown>
</>
);
};
DropdownDemo.displayName = 'DropdownDemo';
Loading

0 comments on commit 9fe5e5a

Please sign in to comment.