Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.

Add useMenuFocus test for ownerRef

+58 -1
src/__tests__/useMenuFocus.test.tsx
···
-
import React, { useState, useRef } from 'react';
import { mount } from '@cypress/react';
import { useMenuFocus } from '../useMenuFocus';
···
cy.realPress('ArrowUp');
cy.get('@input').should('be.focused');
});
···
+
import React, { useRef } from 'react';
import { mount } from '@cypress/react';
import { useMenuFocus } from '../useMenuFocus';
···
cy.realPress('ArrowUp');
cy.get('@input').should('be.focused');
});
+
+
it('supports being attached to an owner element', () => {
+
const Menu = () => {
+
const ownerRef = useRef<HTMLInputElement>(null);
+
const ref = useRef<HTMLUListElement>(null);
+
+
useMenuFocus(ref, { ownerRef });
+
+
return (
+
<main>
+
<input type="search" name="search" ref={ownerRef} />
+
<ul ref={ref}>
+
<li tabIndex={0}>#1</li>
+
<li tabIndex={0}>#2</li>
+
<li tabIndex={0}>#3</li>
+
</ul>
+
</main>
+
);
+
};
+
+
mount(<Menu />);
+
+
// focus the input
+
cy.get('input').first().as('input').focus();
+
cy.focused().should('have.property.name', 'search');
+
+
// pressing escape on input shouldn't change focus
+
cy.realPress('Escape');
+
cy.get('@input').should('have.focus');
+
+
// pressing arrow down should start focusing the menu
+
cy.get('@input').focus();
+
cy.realPress('ArrowDown');
+
cy.focused().contains('#1');
+
+
// pressing arrow up should start focusing the last item
+
cy.get('@input').focus();
+
cy.realPress('ArrowUp');
+
cy.focused().contains('#3');
+
+
// pressing arrow up should start focusing the last item
+
cy.get('@input').focus();
+
cy.realPress('Enter');
+
cy.focused().contains('#1');
+
+
// typing regular values should refocus the owner input
+
cy.get('li').first().focus();
+
cy.realType('test');
+
cy.get('@input')
+
.should('have.focus')
+
.should('have.value', 'test');
+
+
// pressing escape should refocus input
+
cy.get('li').first().focus();
+
cy.realPress('Escape');
+
cy.get('@input').should('have.focus');
+
});
+2 -3
src/useDialogFocus.ts
···
contains(owner, active) &&
event.code === 'Enter'
) {
-
// Move focus to first target when enter is pressed
-
event.preventDefault();
const newTarget = getFirstFocusTarget(ref.current);
if (newTarget) {
willReceiveFocus = true;
newTarget.focus();
}
···
/^(?:Key|Digit)/.test(event.code)
) {
// Restore selection if a key is pressed on input
-
event.preventDefault();
willReceiveFocus = false;
restoreSelection(selection);
}
···
contains(owner, active) &&
event.code === 'Enter'
) {
+
// Move focus to first target when Enter is pressed
const newTarget = getFirstFocusTarget(ref.current);
if (newTarget) {
+
event.preventDefault();
willReceiveFocus = true;
newTarget.focus();
}
···
/^(?:Key|Digit)/.test(event.code)
) {
// Restore selection if a key is pressed on input
willReceiveFocus = false;
restoreSelection(selection);
}
-1
src/useMenuFocus.ts
···
/^(?:Key|Digit)/.test(event.code)
) {
// Restore selection if a key is pressed on input
-
event.preventDefault();
restoreSelection(selection);
}
}
···
/^(?:Key|Digit)/.test(event.code)
) {
// Restore selection if a key is pressed on input
restoreSelection(selection);
}
}