diff --git a/packages/react-events/docs/FocusScope.md b/packages/react-events/docs/FocusScope.md
deleted file mode 100644
index 996a4e3de5e47..0000000000000
--- a/packages/react-events/docs/FocusScope.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# FocusScope
-
-The `FocusScope` module can be used to manage focus within its subtree.
-
-```js
-// Example
-const Modal = () => (
-
- Focus contained within modal
-
- Focusable element
-
-
- Close
-
-
-);
-```
-
-## Props
-
-### autoFocus: boolean = false
-
-Automatically moves focus to the first focusable element within scope.
-
-### contain: boolean = false
-
-Contain focus within the subtree of the `FocusScope` instance.
-
-### restoreFocus: boolean = false
-
-Automatically restores focus to element that was last focused before focus moved
-within the scope.
diff --git a/packages/react-events/focus-scope.js b/packages/react-events/focus-scope.js
deleted file mode 100644
index 5748f99e7748d..0000000000000
--- a/packages/react-events/focus-scope.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @flow
- */
-
-'use strict';
-
-module.exports = require('./src/dom/FocusScope');
diff --git a/packages/react-events/npm/focus-scope.js b/packages/react-events/npm/focus-scope.js
deleted file mode 100644
index 0608f1826aa62..0000000000000
--- a/packages/react-events/npm/focus-scope.js
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict';
-
-if (process.env.NODE_ENV === 'production') {
- module.exports = require('./cjs/react-events-focus-scope.production.min.js');
-} else {
- module.exports = require('./cjs/react-events-focus-scope.development.js');
-}
diff --git a/packages/react-events/package.json b/packages/react-events/package.json
index fa12895c074f0..7135dc53b4ce6 100644
--- a/packages/react-events/package.json
+++ b/packages/react-events/package.json
@@ -18,7 +18,6 @@
"swipe.js",
"drag.js",
"scroll.js",
- "focus-scope.js",
"input.js",
"keyboard.js",
"build-info.json",
diff --git a/packages/react-events/src/dom/FocusScope.js b/packages/react-events/src/dom/FocusScope.js
deleted file mode 100644
index f19bdb5a0eb5e..0000000000000
--- a/packages/react-events/src/dom/FocusScope.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @flow
- */
-import type {
- ReactDOMResponderEvent,
- ReactDOMResponderContext,
-} from 'shared/ReactDOMTypes';
-
-import React from 'react';
-
-type FocusScopeProps = {
- autoFocus: Boolean,
- contain: Boolean,
- restoreFocus: Boolean,
-};
-
-type FocusScopeState = {
- nodeToRestore: null | HTMLElement,
- currentFocusedNode: null | HTMLElement,
-};
-
-const targetEventTypes = ['keydown_active'];
-const rootEventTypes = ['focus'];
-
-function focusElement(element: ?HTMLElement) {
- if (element != null) {
- try {
- element.focus();
- } catch (err) {}
- }
-}
-
-function getFirstFocusableElement(
- context: ReactDOMResponderContext,
- state: FocusScopeState,
-): ?HTMLElement {
- const elements = context.getFocusableElementsInScope(false);
- if (elements.length > 0) {
- return elements[0];
- }
-}
-
-const focusScopeResponderImpl = {
- targetEventTypes,
- rootEventTypes,
- getInitialState(): FocusScopeState {
- return {
- nodeToRestore: null,
- currentFocusedNode: null,
- };
- },
- onEvent(
- event: ReactDOMResponderEvent,
- context: ReactDOMResponderContext,
- props: FocusScopeProps,
- state: FocusScopeState,
- ) {
- const {type, nativeEvent} = event;
-
- if (type === 'keydown' && nativeEvent.key === 'Tab') {
- const focusedElement = context.getActiveDocument().activeElement;
- if (
- focusedElement !== null &&
- context.isTargetWithinResponder(focusedElement)
- ) {
- const {altkey, ctrlKey, metaKey, shiftKey} = (nativeEvent: any);
- // Skip if any of these keys are being pressed
- if (altkey || ctrlKey || metaKey) {
- return;
- }
- const elements = context.getFocusableElementsInScope(false);
- const position = elements.indexOf(focusedElement);
- const lastPosition = elements.length - 1;
- let nextElement = null;
-
- if (shiftKey) {
- if (position === 0) {
- if (props.contain) {
- nextElement = elements[lastPosition];
- } else {
- // Out of bounds
- // TODO remove this, this is hacky
- const allElements = context.getFocusableElementsInScope(true);
- const prevPosition = allElements.indexOf(focusedElement) - 1;
- nextElement = allElements[prevPosition] || null;
- return;
- }
- } else {
- nextElement = elements[position - 1];
- }
- } else {
- if (position === lastPosition) {
- if (props.contain) {
- nextElement = elements[0];
- } else {
- // Out of bounds
- // TODO remove this, this is hacky
- const allElements = context.getFocusableElementsInScope(true);
- const nextPosition = allElements.indexOf(focusedElement) + 1;
- nextElement = allElements[nextPosition] || null;
- }
- } else {
- nextElement = elements[position + 1];
- }
- }
- if (nextElement !== null) {
- focusElement(nextElement);
- state.currentFocusedNode = nextElement;
- ((nativeEvent: any): KeyboardEvent).preventDefault();
- }
- }
- }
- },
- onRootEvent(
- event: ReactDOMResponderEvent,
- context: ReactDOMResponderContext,
- props: FocusScopeProps,
- state: FocusScopeState,
- ) {
- const {target} = event;
-
- // Handle global focus containment
- if (props.contain) {
- if (!context.isTargetWithinResponder(target)) {
- const currentFocusedNode = state.currentFocusedNode;
- if (currentFocusedNode !== null) {
- focusElement(currentFocusedNode);
- } else if (props.autoFocus) {
- const firstElement = getFirstFocusableElement(context, state);
- focusElement(firstElement);
- }
- }
- }
- },
- onMount(
- context: ReactDOMResponderContext,
- props: FocusScopeProps,
- state: FocusScopeState,
- ): void {
- if (props.restoreFocus) {
- state.nodeToRestore = context.getActiveDocument().activeElement;
- }
- if (props.autoFocus) {
- const firstElement = getFirstFocusableElement(context, state);
- focusElement(firstElement);
- }
- },
- onUnmount(
- context: ReactDOMResponderContext,
- props: FocusScopeProps,
- state: FocusScopeState,
- ): void {
- if (props.restoreFocus && state.nodeToRestore !== null) {
- focusElement(state.nodeToRestore);
- }
- },
-};
-
-export const FocusScopeResponder = React.unstable_createResponder(
- 'FocusSocpe',
- focusScopeResponderImpl,
-);
diff --git a/packages/react-events/src/dom/__tests__/FocusScope-test.internal.js b/packages/react-events/src/dom/__tests__/FocusScope-test.internal.js
deleted file mode 100644
index 1261817e65b52..0000000000000
--- a/packages/react-events/src/dom/__tests__/FocusScope-test.internal.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @emails react-core
- */
-
-'use strict';
-
-let React;
-let ReactFeatureFlags;
-let ReactDOM;
-let FocusScopeResponder;
-
-const createTabForward = type => {
- const event = new KeyboardEvent('keydown', {
- key: 'Tab',
- bubbles: true,
- cancelable: true,
- });
- return event;
-};
-
-const createTabBackward = type => {
- const event = new KeyboardEvent('keydown', {
- key: 'Tab',
- shiftKey: true,
- bubbles: true,
- cancelable: true,
- });
- return event;
-};
-
-describe('FocusScope event responder', () => {
- let container;
-
- beforeEach(() => {
- jest.resetModules();
- ReactFeatureFlags = require('shared/ReactFeatureFlags');
- ReactFeatureFlags.enableFlareAPI = true;
- React = require('react');
- ReactDOM = require('react-dom');
- FocusScopeResponder = require('react-events/focus-scope')
- .FocusScopeResponder;
- container = document.createElement('div');
- document.body.appendChild(container);
- });
-
- afterEach(() => {
- ReactDOM.render(null, container);
- document.body.removeChild(container);
- container = null;
- });
-
- it('should work as expected with autofocus', () => {
- const inputRef = React.createRef();
- const input2Ref = React.createRef();
- const buttonRef = React.createRef();
- const butto2nRef = React.createRef();
- const divRef = React.createRef();
-
- const SimpleFocusScope = () => (
-
}>
-
-
-
-
-
-
- );
-
- ReactDOM.render(, container);
- expect(document.activeElement).toBe(inputRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(divRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(butto2nRef.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(divRef.current);
- });
-
- it('should work as expected with autoFocus and contain', () => {
- const inputRef = React.createRef();
- const input2Ref = React.createRef();
- const buttonRef = React.createRef();
- const button2Ref = React.createRef();
-
- const SimpleFocusScope = () => (
- }>
-
-
-
-
-
- );
-
- ReactDOM.render(, container);
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button2Ref.current);
- });
-
- it('should work as expected when nested', () => {
- const inputRef = React.createRef();
- const input2Ref = React.createRef();
- const buttonRef = React.createRef();
- const button2Ref = React.createRef();
- const button3Ref = React.createRef();
- const button4Ref = React.createRef();
-
- const SimpleFocusScope = () => (
- }>
-
-
- }>
-
-
-
-
-
-
- );
-
- ReactDOM.render(, container);
- buttonRef.current.focus();
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button4Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button2Ref.current);
- });
-
- it('should work as expected when nested with scope that is contained', () => {
- const inputRef = React.createRef();
- const input2Ref = React.createRef();
- const buttonRef = React.createRef();
- const button2Ref = React.createRef();
- const button3Ref = React.createRef();
- const button4Ref = React.createRef();
-
- const SimpleFocusScope = () => (
- }>
-
-
- }>
-
-
-
-
-
-
- );
-
- ReactDOM.render(, container);
- buttonRef.current.focus();
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button2Ref.current);
- });
-
- it('should work as expected with suspense fallbacks', () => {
- const buttonRef = React.createRef();
- const button2Ref = React.createRef();
- const button3Ref = React.createRef();
- const button4Ref = React.createRef();
- const button5Ref = React.createRef();
-
- function SuspendedComponent() {
- throw new Promise(() => {
- // Never resolve
- });
- }
-
- function Component() {
- return (
-
-
-
-
- );
- }
-
- const SimpleFocusScope = () => (
- }>
-
-
- }>
-
-
-
-
- );
-
- ReactDOM.render(, container);
- buttonRef.current.focus();
- expect(document.activeElement).toBe(buttonRef.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button2Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabForward());
- expect(document.activeElement).toBe(button4Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button3Ref.current);
- document.activeElement.dispatchEvent(createTabBackward());
- expect(document.activeElement).toBe(button2Ref.current);
- });
-});
diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js
index a3e87a9c50670..ca0f79af7cd83 100644
--- a/scripts/rollup/bundles.js
+++ b/scripts/rollup/bundles.js
@@ -464,21 +464,6 @@ const bundles = [
externals: ['react'],
},
- {
- bundleTypes: [
- UMD_DEV,
- UMD_PROD,
- NODE_DEV,
- NODE_PROD,
- FB_WWW_DEV,
- FB_WWW_PROD,
- ],
- moduleType: NON_FIBER_RENDERER,
- entry: 'react-events/focus-scope',
- global: 'ReactEventsFocusScope',
- externals: ['react'],
- },
-
{
bundleTypes: [
UMD_DEV,