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 ( +
+ +

Popup Content

+
+ +
+ +
+ +
+ ); + } +} + +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', () => {