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

Configure Feed

Select the types of activity you want to include in your feed.

Add useMenuFocus test for ownerRef

+60 -5
+58 -1
src/__tests__/useMenuFocus.test.tsx
··· 1 - import React, { useState, useRef } from 'react'; 1 + import React, { useRef } from 'react'; 2 2 import { mount } from '@cypress/react'; 3 3 4 4 import { useMenuFocus } from '../useMenuFocus'; ··· 85 85 cy.realPress('ArrowUp'); 86 86 cy.get('@input').should('be.focused'); 87 87 }); 88 + 89 + it('supports being attached to an owner element', () => { 90 + const Menu = () => { 91 + const ownerRef = useRef<HTMLInputElement>(null); 92 + const ref = useRef<HTMLUListElement>(null); 93 + 94 + useMenuFocus(ref, { ownerRef }); 95 + 96 + return ( 97 + <main> 98 + <input type="search" name="search" ref={ownerRef} /> 99 + <ul ref={ref}> 100 + <li tabIndex={0}>#1</li> 101 + <li tabIndex={0}>#2</li> 102 + <li tabIndex={0}>#3</li> 103 + </ul> 104 + </main> 105 + ); 106 + }; 107 + 108 + mount(<Menu />); 109 + 110 + // focus the input 111 + cy.get('input').first().as('input').focus(); 112 + cy.focused().should('have.property.name', 'search'); 113 + 114 + // pressing escape on input shouldn't change focus 115 + cy.realPress('Escape'); 116 + cy.get('@input').should('have.focus'); 117 + 118 + // pressing arrow down should start focusing the menu 119 + cy.get('@input').focus(); 120 + cy.realPress('ArrowDown'); 121 + cy.focused().contains('#1'); 122 + 123 + // pressing arrow up should start focusing the last item 124 + cy.get('@input').focus(); 125 + cy.realPress('ArrowUp'); 126 + cy.focused().contains('#3'); 127 + 128 + // pressing arrow up should start focusing the last item 129 + cy.get('@input').focus(); 130 + cy.realPress('Enter'); 131 + cy.focused().contains('#1'); 132 + 133 + // typing regular values should refocus the owner input 134 + cy.get('li').first().focus(); 135 + cy.realType('test'); 136 + cy.get('@input') 137 + .should('have.focus') 138 + .should('have.value', 'test'); 139 + 140 + // pressing escape should refocus input 141 + cy.get('li').first().focus(); 142 + cy.realPress('Escape'); 143 + cy.get('@input').should('have.focus'); 144 + });
+2 -3
src/useDialogFocus.ts
··· 146 146 contains(owner, active) && 147 147 event.code === 'Enter' 148 148 ) { 149 - // Move focus to first target when enter is pressed 150 - event.preventDefault(); 149 + // Move focus to first target when Enter is pressed 151 150 const newTarget = getFirstFocusTarget(ref.current); 152 151 if (newTarget) { 152 + event.preventDefault(); 153 153 willReceiveFocus = true; 154 154 newTarget.focus(); 155 155 } ··· 160 160 /^(?:Key|Digit)/.test(event.code) 161 161 ) { 162 162 // Restore selection if a key is pressed on input 163 - event.preventDefault(); 164 163 willReceiveFocus = false; 165 164 restoreSelection(selection); 166 165 }
-1
src/useMenuFocus.ts
··· 119 119 /^(?:Key|Digit)/.test(event.code) 120 120 ) { 121 121 // Restore selection if a key is pressed on input 122 - event.preventDefault(); 123 122 restoreSelection(selection); 124 123 } 125 124 }