Skip to content

Commit fa3862e

Browse files
authored
fix: enhance FocusScope to support tab completion for IMEs (#5909)
* fix: Improve tab completion for IMEs
1 parent fd3f09c commit fa3862e

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

packages/@react-aria/focus/src/FocusScope.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ function useFocusContainment(scopeRef: RefObject<Element[]>, contain?: boolean)
314314

315315
// Handle the Tab key to contain focus within the scope
316316
let onKeyDown = (e) => {
317-
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !shouldContainFocus(scopeRef)) {
317+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !shouldContainFocus(scopeRef) || e.isComposing) {
318318
return;
319319
}
320320

@@ -585,7 +585,7 @@ function useRestoreFocus(scopeRef: RefObject<Element[]>, restoreFocus?: boolean,
585585
// using portals for overlays, so that focus goes to the expected element when
586586
// tabbing out of the overlay.
587587
let onKeyDown = (e: KeyboardEvent) => {
588-
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !shouldContainFocus(scopeRef)) {
588+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !shouldContainFocus(scopeRef) || e.isComposing) {
589589
return;
590590
}
591591

packages/@react-aria/focus/stories/FocusScope.stories.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,67 @@ export const IgnoreRestoreFocus = {
210210
export const FocusableFirstInScope = {
211211
render: () => <FocusableFirstInScopeExample />
212212
};
213+
214+
215+
function FocusableInputFormExample(args) {
216+
let [isOpen, setOpen] = React.useState(false);
217+
let {contain, restoreFocus, autoFocus} = args;
218+
219+
return (
220+
<>
221+
<button onClick={() => setOpen(true)}>Open</button>
222+
{isOpen && (
223+
<>
224+
<div style={{display: 'flex', flexDirection: 'column', marginBottom: '10px'}}>
225+
<FocusScope contain={contain} restoreFocus={restoreFocus} autoFocus={autoFocus}>
226+
<label htmlFor="first-input">First Input</label>
227+
<input id="first-input" />
228+
<label htmlFor="second-input">Second Input</label>
229+
<input id="second-input" />
230+
</FocusScope>
231+
</div>
232+
<div style={{display: 'flex', flexDirection: 'column'}}>
233+
<label htmlFor="third-input">Third Input</label>
234+
<input id="third-input" />
235+
</div>
236+
<button onClick={() => setOpen(false)}>Close</button>
237+
</>
238+
)}
239+
</>
240+
);
241+
}
242+
243+
export const FocusableInputForm = {
244+
name: 'FocusableInputForm',
245+
render: (args) => <FocusableInputFormExample {...args} />,
246+
args: {
247+
contain: true,
248+
restoreFocus: true,
249+
autoFocus: true
250+
},
251+
argTypes: {
252+
contain: {
253+
control: 'boolean'
254+
},
255+
restoreFocus: {
256+
control: 'boolean'
257+
},
258+
autoFocus: {
259+
control: 'boolean'
260+
}
261+
},
262+
parameters: {
263+
description: {
264+
data: `
265+
1. Open OS keyboard settings
266+
2. Add Chinese Pinyin - Simplified
267+
3. Go to the third input
268+
4. Type "ni", a set of suggestions should appear
269+
5. Press Tab 3x and see how it shows different suggestions
270+
6. Go to the first input
271+
7. Repeat steps 4&5
272+
8. See how it leaves the suggestions and jumps to the form button
273+
`
274+
}
275+
}
276+
};

0 commit comments

Comments
 (0)