diff --git a/packages/@react-aria/selection/src/useTypeSelect.ts b/packages/@react-aria/selection/src/useTypeSelect.ts
index 19b9a9b0655..51b80dcd675 100644
--- a/packages/@react-aria/selection/src/useTypeSelect.ts
+++ b/packages/@react-aria/selection/src/useTypeSelect.ts
@@ -53,7 +53,7 @@ export function useTypeSelect(options: AriaTypeSelectOptions): TypeSelectAria {
let onKeyDown = (e: KeyboardEvent) => {
let character = getStringForKey(e.key);
- if (!character || e.ctrlKey || e.metaKey) {
+ if (!character || e.ctrlKey || e.metaKey || !e.currentTarget.contains(e.target as HTMLElement)) {
return;
}
diff --git a/packages/@react-spectrum/table/stories/Table.stories.tsx b/packages/@react-spectrum/table/stories/Table.stories.tsx
index 03fb745c1b5..9ad3841ef26 100644
--- a/packages/@react-spectrum/table/stories/Table.stories.tsx
+++ b/packages/@react-spectrum/table/stories/Table.stories.tsx
@@ -1791,3 +1791,53 @@ export const ResizingControlledHideHeader: TableStory = {
`}}
};
+let typeAheadColumns = [
+ {name: 'First Name', id: 'firstname', isRowHeader: true},
+ {name: 'Last Name', id: 'lastname', isRowHeader: true},
+ {name: 'Birthday', id: 'birthday'},
+ {name: 'Edit', id: 'edit'}
+];
+let typeAheadRows = [
+ ...Array.from({length: 100}, (v, i) => ({id: i, firstname: 'Aubrey', lastname: 'Sheppard', birthday: 'May 7'})),
+ {id: 101, firstname: 'John', lastname: 'Doe', birthday: 'May 7'}
+];
+export const TypeaheadWithDialog: TableStory = {
+ render: (args) => (
+
+
+
+ {(col) => (
+ {col.name}
+ )}
+
+
+ {(item) => (
+
+ {(key) =>
+ key === 'edit' ? (
+ |
+
+
+
+
+
+
+ |
+ ) : (
+ {item[key]} |
+ )
+ }
+
+ )}
+
+
+
+ )
+};
+
diff --git a/packages/@react-spectrum/table/test/Table.test.js b/packages/@react-spectrum/table/test/Table.test.js
index 971f3b8f605..fe1904a84a4 100644
--- a/packages/@react-spectrum/table/test/Table.test.js
+++ b/packages/@react-spectrum/table/test/Table.test.js
@@ -36,7 +36,8 @@ import userEvent from '@testing-library/user-event';
let {
InlineDeleteButtons: DeletableRowsTable,
EmptyStateStory: EmptyStateTable,
- WithBreadcrumbNavigation: TableWithBreadcrumbs
+ WithBreadcrumbNavigation: TableWithBreadcrumbs,
+ TypeaheadWithDialog: TypeaheadWithDialog
} = composeStories(stories);
@@ -1412,6 +1413,43 @@ describe('TableView', function () {
moveFocus('S');
expect(document.activeElement).toBe(getCell(tree, 'Sam'));
});
+
+ describe('type ahead with dialog triggers', function () {
+ beforeEach(function () {
+ offsetHeight.mockRestore();
+ offsetHeight = jest.spyOn(window.HTMLElement.prototype, 'clientHeight', 'get')
+ .mockImplementationOnce(() => 20)
+ .mockImplementation(() => 100);
+ });
+ afterEach(function () {
+ offsetHeight.mockRestore();
+ offsetHeight = jest.spyOn(window.HTMLElement.prototype, 'clientHeight', 'get').mockImplementation(() => 1000);
+ });
+ it('does not pick up typeahead from a dialog', function () {
+ offsetHeight = jest.spyOn(window.HTMLElement.prototype, 'clientHeight', 'get')
+ .mockImplementationOnce(() => 20)
+ .mockImplementation(() => 100);
+ let tree = render();
+ let trigger = tree.getAllByRole('button')[0];
+ triggerPress(trigger);
+ act(() => {
+ jest.runAllTimers();
+ });
+ let textfield = tree.getByLabelText('Enter a J');
+ act(() => {textfield.focus();});
+ fireEvent.keyDown(textfield, {key: 'J'});
+ fireEvent.keyUp(textfield, {key: 'J'});
+ act(() => {
+ jest.runAllTimers();
+ });
+ expect(document.activeElement).toBe(textfield);
+ fireEvent.keyDown(document.activeElement, {key: 'Escape'});
+ fireEvent.keyUp(document.activeElement, {key: 'Escape'});
+ act(() => {
+ jest.runAllTimers();
+ });
+ });
+ });
});
describe('focus marshalling', function () {