diff --git a/packages/terra-popup/CHANGELOG.md b/packages/terra-popup/CHANGELOG.md
index 46196c5cc8f..138aa8e503a 100644
--- a/packages/terra-popup/CHANGELOG.md
+++ b/packages/terra-popup/CHANGELOG.md
@@ -2,6 +2,9 @@
## Unreleased
+* Changed
+ * Updated popup to have focus on first interactable child when opened.
+
## 6.58.0 - (October 14, 2021)
* Fixed
diff --git a/packages/terra-popup/package.json b/packages/terra-popup/package.json
index 6b0d8e05f4c..da052329fdf 100644
--- a/packages/terra-popup/package.json
+++ b/packages/terra-popup/package.json
@@ -32,6 +32,7 @@
"focus-trap-react": "^6.0.0",
"prop-types": "^15.5.8",
"react-portal": "^4.1.2",
+ "tabbable": "^5.2.1",
"terra-button": "^3.3.0",
"terra-content-container": "^3.0.0",
"terra-hookshot": "^5.38.0",
@@ -53,6 +54,6 @@
"wdio-default": "cd ../.. && terra wdio",
"wdio-lowlight": "cd ../.. && terra wdio --themes clinical-lowlight-theme",
"wdio-fusion": "cd ../.. && terra wdio --themes orion-fusion-theme",
- "wdio": "npm run wdio-default && npm run wdio-lowlight && npm run wdio-fusion"
+ "wdio": "cd ../.. && terra wdio --themes terra-default-theme clinical-lowlight-theme orion-fusion-theme"
}
}
diff --git a/packages/terra-popup/src/_PopupContent.jsx b/packages/terra-popup/src/_PopupContent.jsx
index 29182bdcc3d..8ed5b9b8cf5 100644
--- a/packages/terra-popup/src/_PopupContent.jsx
+++ b/packages/terra-popup/src/_PopupContent.jsx
@@ -8,6 +8,7 @@ import Button from 'terra-button';
import ContentContainer from 'terra-content-container';
import FocusTrap from 'focus-trap-react';
import Hookshot from 'terra-hookshot';
+import { tabbable } from 'tabbable';
import styles from './PopupContent.module.scss';
const cx = classNamesBind.bind(styles);
@@ -113,6 +114,7 @@ class PopupContent extends React.Component {
);
+
return {children};
}
@@ -137,6 +139,7 @@ class PopupContent extends React.Component {
constructor(props) {
super(props);
this.handleOnResize = this.handleOnResize.bind(this);
+ this.popupContentRef = React.createRef();
}
componentDidMount() {
@@ -144,6 +147,25 @@ class PopupContent extends React.Component {
this.windowWidth = window.innerWidth;
}
+ componentDidUpdate() {
+ if (this.popupContentRef && this.popupContentRef.current) {
+ const mainContent = this.popupContentRef.current.querySelector("[class*='main']");
+ const headerContent = this.popupContentRef.current.querySelector("[class*='header']");
+ if (headerContent) {
+ const headerContentFocusableChildren = tabbable(headerContent);
+ if (headerContentFocusableChildren && headerContentFocusableChildren[0]) {
+ headerContentFocusableChildren[0].focus();
+ }
+ }
+ if (mainContent) {
+ const mainContentFocusableChildren = tabbable(mainContent);
+ if (mainContentFocusableChildren && mainContentFocusableChildren[0]) {
+ mainContentFocusableChildren[0].focus();
+ }
+ }
+ }
+ }
+
static getContentStyle(height, maxHeight, width, maxWidth, isHeightAutomatic, isWidthAutomatic) {
const heightStyle = PopupContent.getDimensionStyle(height, maxHeight, isHeightAutomatic);
const widthStyle = PopupContent.getDimensionStyle(width, maxWidth, isWidthAutomatic);
@@ -240,7 +262,7 @@ class PopupContent extends React.Component {
>
{arrowContent}
{/* eslint-disable-next-line react/forbid-dom-props */}
-
+
{content}
diff --git a/packages/terra-popup/src/terra-dev-site/test/popup/BoundedPopupWithInteractableChildren.test.jsx b/packages/terra-popup/src/terra-dev-site/test/popup/BoundedPopupWithInteractableChildren.test.jsx
new file mode 100644
index 00000000000..08f3789d6d1
--- /dev/null
+++ b/packages/terra-popup/src/terra-dev-site/test/popup/BoundedPopupWithInteractableChildren.test.jsx
@@ -0,0 +1,76 @@
+/* eslint-disable jsx-a11y/no-autofocus */
+import React from 'react';
+import classNames from 'classnames/bind';
+import Popup from '../../../Popup';
+import styles from './BoundedPopupCommon.test.module.scss';
+
+const cx = classNames.bind(styles);
+
+class BoundedPopup extends React.Component {
+ constructor(props) {
+ super(props);
+ this.handleButtonClick = this.handleButtonClick.bind(this);
+ this.handleRequestClose = this.handleRequestClose.bind(this);
+ this.setButtonNode = this.setButtonNode.bind(this);
+ this.getButtonNode = this.getButtonNode.bind(this);
+ this.setParentNode = this.setParentNode.bind(this);
+ this.getParentNode = this.getParentNode.bind(this);
+ this.state = { open: false };
+ }
+
+ componentDidMount() {
+ this.forceUpdate();
+ }
+
+ handleButtonClick() {
+ this.setState({ open: true });
+ }
+
+ handleRequestClose() {
+ this.setState({ open: false });
+ }
+
+ setButtonNode(node) {
+ this.buttonNode = node;
+ }
+
+ getButtonNode() {
+ return this.buttonNode;
+ }
+
+ setParentNode(node) {
+ this.parentNode = node;
+ }
+
+ getParentNode() {
+ return this.parentNode;
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+export default BoundedPopup;
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png
new file mode 100644
index 00000000000..3163d021732
Binary files /dev/null and b/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png differ
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/with_header.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/with_header.png
index 465e7597ab8..c3d98c74361 100644
Binary files a/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/with_header.png and b/packages/terra-popup/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_medium/popup-spec/with_header.png differ
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png
new file mode 100644
index 00000000000..056c618ebed
Binary files /dev/null and b/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png differ
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/with_header.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/with_header.png
index c395f4e6a3f..b00ebfdc2e7 100644
Binary files a/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/with_header.png and b/packages/terra-popup/tests/wdio/__snapshots__/reference/orion-fusion-theme/en/chrome_medium/popup-spec/with_header.png differ
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png
new file mode 100644
index 00000000000..3d9e923809e
Binary files /dev/null and b/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/first_interactable_child_focused.png differ
diff --git a/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/with_header.png b/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/with_header.png
index a47efffe22b..3a001a5e445 100644
Binary files a/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/with_header.png and b/packages/terra-popup/tests/wdio/__snapshots__/reference/terra-default-theme/en/chrome_medium/popup-spec/with_header.png differ
diff --git a/packages/terra-popup/tests/wdio/popup-spec.js b/packages/terra-popup/tests/wdio/popup-spec.js
index 432a0595082..5db80a4f286 100644
--- a/packages/terra-popup/tests/wdio/popup-spec.js
+++ b/packages/terra-popup/tests/wdio/popup-spec.js
@@ -84,6 +84,13 @@ Terra.describeViewports('Popup', ['medium'], () => {
$('.test-content').waitForDisplayed();
Terra.validates.element('bounded width', { selector });
});
+
+ it('validates focus to be on first interactable element', () => {
+ browser.url('/raw/tests/terra-popup/popup/bounded-popup-with-interactable-children');
+ $('#bounded-button').click();
+ $('.test-content').waitForDisplayed();
+ Terra.validates.element('first interactable child focused', { selector });
+ });
});
describe('Popup inside a modal', () => {