From dcd9daad3eba0955d500b9c56cb16d76b5fb6c8f Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Wed, 20 Mar 2024 16:30:20 -0400
Subject: [PATCH 01/11] return focus to disclosing node update
---
.../SlidePanelManager.test.jsx.snap | 10 ------
packages/terra-slide-panel/CHANGELOG.md | 3 ++
packages/terra-slide-panel/src/SlidePanel.jsx | 9 +----
.../__snapshots__/SlidePanel.test.jsx.snap | 34 -------------------
.../tests/wdio/slide-panel-spec.js | 2 +-
5 files changed, 5 insertions(+), 53 deletions(-)
diff --git a/packages/terra-slide-panel-manager/tests/jest/__snapshots__/SlidePanelManager.test.jsx.snap b/packages/terra-slide-panel-manager/tests/jest/__snapshots__/SlidePanelManager.test.jsx.snap
index 1756569f80e..f4e221e7099 100644
--- a/packages/terra-slide-panel-manager/tests/jest/__snapshots__/SlidePanelManager.test.jsx.snap
+++ b/packages/terra-slide-panel-manager/tests/jest/__snapshots__/SlidePanelManager.test.jsx.snap
@@ -364,8 +364,6 @@ exports[`SlidePanelManager should disclose content in SlidePanel 1`] = `
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -863,8 +861,6 @@ exports[`SlidePanelManager should render a SlidePanelManager with level three he
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -1130,8 +1126,6 @@ exports[`SlidePanelManager should render the SlidePanelManager with custom props
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -1390,8 +1384,6 @@ exports[`SlidePanelManager should render the SlidePanelManager with defaults 1`]
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -1650,8 +1642,6 @@ exports[`SlidePanelManager should render the SlidePanelManager with squish overr
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
diff --git a/packages/terra-slide-panel/CHANGELOG.md b/packages/terra-slide-panel/CHANGELOG.md
index 42daa35020f..7af7307f7ec 100644
--- a/packages/terra-slide-panel/CHANGELOG.md
+++ b/packages/terra-slide-panel/CHANGELOG.md
@@ -2,6 +2,9 @@
## Unreleased
+* Changed
+ * Updated capturing the disclosing node to accommodate for cases with no `mainContent`
+
## 3.47.0 - (December 18, 2023)
* Changed
diff --git a/packages/terra-slide-panel/src/SlidePanel.jsx b/packages/terra-slide-panel/src/SlidePanel.jsx
index da9f252309b..dc6f1ef5606 100644
--- a/packages/terra-slide-panel/src/SlidePanel.jsx
+++ b/packages/terra-slide-panel/src/SlidePanel.jsx
@@ -90,7 +90,6 @@ class SlidePanel extends React.Component {
super(props);
this.setPanelNode = this.setPanelNode.bind(this);
this.mainNode = React.createRef();
- this.setLastClicked = this.setLastClicked.bind(this);
this.setDisclosingNode = this.setDisclosingNode.bind(this);
this.mainAriaDescribedByID = `detail-panel-warning-${uuidv4()}`;
}
@@ -98,7 +97,7 @@ class SlidePanel extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.isOpen && this.props.isOpen !== prevProps.isOpen) {
// Save the disclosing node for returning focus when panel is closed
- this.setDisclosingNode(this.lastClicked);
+ this.setDisclosingNode(document.activeElement);
this.panelNode.focus();
return;
}
@@ -122,10 +121,6 @@ class SlidePanel extends React.Component {
this.panelNode = node;
}
- setLastClicked(event) {
- this.lastClicked = event.target;
- }
-
setDisclosingNode(node) {
if (node) {
node.setAttribute('aria-expanded', 'true');
@@ -189,8 +184,6 @@ class SlidePanel extends React.Component {
aria-hidden={isOpen && isFullscreen ? 'true' : 'false'}
ref={this.mainNode}
role="main"
- onClick={this.setLastClicked}
- onKeyUp={this.setLastClicked}
>
@@ -50,8 +48,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with an open s
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -88,8 +84,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with fill 1`]
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -126,8 +120,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with main cont
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -167,8 +159,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with main cont
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -211,8 +201,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panel con
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -253,8 +241,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelAria
aria-label="Main content area"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -291,8 +277,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelBeha
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -329,8 +313,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelBeha
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -367,8 +349,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelPosi
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -417,8 +397,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelPosi
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -443,8 +421,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelSize
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -481,8 +457,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelSize
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -521,8 +495,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with the given
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -661,8 +633,6 @@ exports[`When custom props are used correctly applies the theme context classNam
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -716,8 +686,6 @@ exports[`When custom props are used sets aria-hidden to true on main content div
aria-hidden="true"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
@@ -755,8 +723,6 @@ exports[`When custom props are used should override user provided attributes tha
aria-hidden="false"
className="main"
key="main"
- onClick={[Function]}
- onKeyUp={[Function]}
role="main"
tabIndex="-1"
>
diff --git a/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js b/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
index 115e5d5769b..44ebc435bbc 100644
--- a/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
+++ b/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
@@ -206,7 +206,7 @@ Terra.describeViewports('Slide panel', ['large'], () => {
expect($('#focus-button').isFocused()).toBeTruthy();
browser.keys(['Enter']);
- expect($('body').isFocused()).toBeTruthy();
+ expect($('[aria-label="Main content area"]').isFocused()).toBeTruthy();
expect($('#test-click-svg').isFocused()).toBeFalsy();
});
From e56f1f0f30bee749e497e01f328b872b56bfc7c9 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Fri, 22 Mar 2024 13:08:07 -0400
Subject: [PATCH 02/11] set aria-expanded attribute to elements with associated
roles only
---
.../close_from_explicit_close.png | Bin 7030 -> 6934 bytes
.../close_from_explicit_close.png | Bin 6817 -> 6834 bytes
.../close_from_explicit_close.png | Bin 7110 -> 7120 bytes
packages/terra-slide-panel/src/SlidePanel.jsx | 48 +++++++++++++++---
4 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/packages/terra-aggregator/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_large/aggregator-spec/close_from_explicit_close.png b/packages/terra-aggregator/tests/wdio/__snapshots__/reference/clinical-lowlight-theme/en/chrome_large/aggregator-spec/close_from_explicit_close.png
index 7a575742e40c2e12bdb26230e62c8e98ddbbf9b5..c5ad102e4f7a330d4063d1c7f23ebac5901f6d47 100644
GIT binary patch
literal 6934
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
H`=9?0pp)SP
literal 6817
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
R0IM1tKkEAp?eMvu{|9+4iD>`;
literal 7110
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
N>$vZ?wcmvQ{6Fkye=Yz3
diff --git a/packages/terra-slide-panel/src/SlidePanel.jsx b/packages/terra-slide-panel/src/SlidePanel.jsx
index dc6f1ef5606..839ce5046a5 100644
--- a/packages/terra-slide-panel/src/SlidePanel.jsx
+++ b/packages/terra-slide-panel/src/SlidePanel.jsx
@@ -85,6 +85,32 @@ const defaultProps = {
panelSize: 'small',
};
+/**
+ * This method ensures that aria-expanded attribute is allowed with the node role to avoid accessibility violations.
+ * More info on associated roles can be found here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded#associated_roles
+ * @param {HTMLElement} node - a node to check
+ * @returns true if node's role is compatible with aria-expanded attribute
+ */
+const roleIsCompartible = (node) => {
+ const role = node.getAttribute('role');
+ return (
+ role === 'application'
+ || role === 'button'
+ || role === 'checkbox'
+ || role === 'combobox'
+ || role === 'gridcell'
+ || role === 'link'
+ || role === 'listbox'
+ || role === 'menuitem'
+ || role === 'row'
+ || role === 'rowheader'
+ || role === 'tab'
+ || role === 'treeitem'
+ || role === null
+ || role === undefined
+ );
+};
+
class SlidePanel extends React.Component {
constructor(props) {
super(props);
@@ -105,12 +131,19 @@ class SlidePanel extends React.Component {
if (!this.props.isOpen && this.props.isOpen !== prevProps.isOpen) {
if (this.disclosingNode?.focus) {
// Return focus to the disclosing element
- this.disclosingNode.setAttribute('aria-expanded', 'false');
+ if (this.disclosingNode.getAttribute('aria-expanded')) {
+ // Set aria-expanded attribute to false for nodes that had that attribute only
+ this.disclosingNode.setAttribute('aria-expanded', 'false');
+ }
this.disclosingNode.focus();
return;
}
- // The disclosing element doesn't exist or isn't focusable, return focus to the main div
- this.mainNode.current.focus();
+ // The disclosing element doesn't exist or isn't focusable, return focus to the main div or body
+ if (this.mainNode?.current) {
+ this.mainNode.current.focus();
+ } else {
+ document.body.focus();
+ }
}
}
@@ -123,7 +156,10 @@ class SlidePanel extends React.Component {
setDisclosingNode(node) {
if (node) {
- node.setAttribute('aria-expanded', 'true');
+ if (roleIsCompartible(node)) {
+ // Set aria-expanded attribute to true for nodes with associated roles or no role only
+ node.setAttribute('aria-expanded', 'true');
+ }
this.disclosingNode = node;
}
}
@@ -197,11 +233,11 @@ class SlidePanel extends React.Component {
const content = (panelPosition === SlidePanelPositions.START) ? (
{panelDiv}
- {mainDiv}
+ {mainContent && mainDiv}
) : (
- {mainDiv}
+ {mainContent && mainDiv}
{panelDiv}
);
From 43981b3f023959a719193ba263c9e111832daa95 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Fri, 22 Mar 2024 14:48:32 -0400
Subject: [PATCH 03/11] existing jest tests and snapshots updated
---
.../tests/jest/SlidePanel.test.jsx | 8 +-
.../__snapshots__/SlidePanel.test.jsx.snap | 196 +-----------------
2 files changed, 10 insertions(+), 194 deletions(-)
diff --git a/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx b/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
index a7afab860b1..6412e38e9ba 100644
--- a/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
+++ b/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
@@ -138,7 +138,7 @@ describe('When a SlidePanel is rendered', () => {
});
it('should render a SlidePanel with panelAriaLabel and mainAriaLabel specified', () => {
- const slidePanel = ;
+ const slidePanel = Main Content
} mainAriaLabel="Main content area" />;
const wrapper = enzymeIntl.shallowWithIntl(slidePanel).dive();
const panelDiv = wrapper.find('.panel');
@@ -163,7 +163,7 @@ describe('When a SlidePanel is rendered', () => {
});
it('should contain a Visually Hidden Text as the aria-describedby target', () => {
- const slidePanel = ;
+ const slidePanel = Main Content} />;
const wrapper = enzymeIntl.shallowWithIntl(slidePanel).dive();
const mainDiv = wrapper.find('#detail-panel-warning-00000000-0000-0000-0000-000000000000').prop('text');
@@ -171,7 +171,7 @@ describe('When a SlidePanel is rendered', () => {
});
it('should set the text property of Visually Hidden Text from ./translations', () => {
- const slidePanel = ;
+ const slidePanel = Main Content} /> ;
const wrapper = enzymeIntl.shallowWithIntl(slidePanel).dive().dive();
const mainDiv = wrapper.find('#detail-panel-warning-00000000-0000-0000-0000-000000000000').prop('text');
@@ -202,7 +202,7 @@ describe('When custom props are used', () => {
});
it('sets aria-hidden to true on main content div when isOpen and isFullscreen props are both true', () => {
- const slidePanel = ;
+ const slidePanel = Main Content} isOpen isFullscreen />;
const wrapper = enzymeIntl.shallowWithIntl(slidePanel).dive();
const mainDiv = wrapper.find('.main');
diff --git a/packages/terra-slide-panel/tests/jest/__snapshots__/SlidePanel.test.jsx.snap b/packages/terra-slide-panel/tests/jest/__snapshots__/SlidePanel.test.jsx.snap
index e5f3c7858ce..b37666cb50b 100644
--- a/packages/terra-slide-panel/tests/jest/__snapshots__/SlidePanel.test.jsx.snap
+++ b/packages/terra-slide-panel/tests/jest/__snapshots__/SlidePanel.test.jsx.snap
@@ -7,20 +7,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with a fullscr
data-slide-panel-panel-position="end"
data-slide-panel-panel-size="small"
>
-
-
-
-
-
-
-
-
-
-
-
-
`;
@@ -416,20 +307,6 @@ exports[`When a SlidePanel is rendered should render a SlidePanel with panelSize
data-slide-panel-panel-position="end"
data-slide-panel-panel-size="large"
>
-
-
-
-
-
-
-
-
-
-
-
-
- Terra.slidePanel.discloseWarning
-
-
-
+
+ Main Content
+
-
-
-
Date: Mon, 25 Mar 2024 09:49:39 -0400
Subject: [PATCH 04/11] no main content example and tests added
---
.../SlidePanelNoMainContent.test.jsx | 102 ++++++++++++++++++
.../SlidePanelNoMainContent.test.module.scss | 41 +++++++
.../tests/jest/SlidePanel.test.jsx | 9 ++
.../tests/wdio/slide-panel-spec.js | 89 +++++++++++++--
4 files changed, 234 insertions(+), 7 deletions(-)
create mode 100644 packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.jsx
create mode 100644 packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
diff --git a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.jsx b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.jsx
new file mode 100644
index 00000000000..a7cb53b40d5
--- /dev/null
+++ b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.jsx
@@ -0,0 +1,102 @@
+import React, { useState } from 'react';
+import SlidePanel, { SlidePanelPositions } from 'terra-slide-panel';
+import classNames from 'classnames/bind';
+import styles from './SlidePanelNoMainContent.test.module.scss';
+
+const cx = classNames.bind(styles);
+
+const mainContentForSlidePanel = (togglePanelHandler) => (
+
+
+ Main Content
+ Toggle Panel 1
+ {/* eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role */}
+ Toggle Panel 2
+ { /* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions */}
+ Toggle Panel 3
+
+
+
+ This is the main content area of the slide panel.
+ The overall height of the SlidePanel is determined by
+ the intrinsic height of the content in this container.
+
+
+ {'Focus is moved to the toggle button in the panel container when the panel is opened via the componentDidUpdate lifecycle hook in '}
+ the example code
+ .
+
+
+ Item 1
+ Item 2
+ Item 3
+ Item 4
+ Item 5
+ Item 6
+ Item 7
+ Item 8
+
+
+
+);
+
+const panelContentForSlidePanel = (togglePanelHandler) => (
+
+
+ Panel Content
+ Toggle Panel
+
+
+
This is the panel content area of the slide panel.
+
+ {'Focus is moved to the toggle button in the main container when the panel is closed via the componentDidUpdate lifecycle hook in '}
+ the example code
+ .
+
+
+ Item 1
+ Item 2
+ Item 3
+ Item 4
+ Item 5
+ Item 6
+ Item 7
+ Item 8
+ Item 9
+ Item 10
+ Item 11
+ Item 12
+ Item 13
+ Item 14
+ Item 15
+
+
+
+);
+
+const SlidePanelNoMainContent = () => {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const handlePanelToggle = () => {
+ setIsOpen(!isOpen);
+ };
+
+ return (
+
+ {mainContentForSlidePanel(handlePanelToggle)}
+
+
+
+
+ );
+};
+
+export default SlidePanelNoMainContent;
diff --git a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
new file mode 100644
index 00000000000..26888cd3cf1
--- /dev/null
+++ b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
@@ -0,0 +1,41 @@
+:local {
+ .example-container {
+ position: relative;
+ }
+
+ .panel-container {
+ & > div:first-child {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 0;
+ }
+ }
+
+ .header-content {
+ background-color: #d3d3d3;
+ p {
+ width: auto;
+ display: inline-block;
+ margin: 0 !important;
+ }
+ & > :not(:last-child){
+ margin-right: 5px;
+ }
+ }
+
+ .header-content h3 {
+ display: inline-block;
+ margin: 0;
+ padding: 5px;
+ }
+
+ .content-wrapper {
+ margin: 5px;
+ }
+
+ .custom-button {
+ display: inline-block;
+ }
+ }
\ No newline at end of file
diff --git a/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx b/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
index 6412e38e9ba..e55dc7502d0 100644
--- a/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
+++ b/packages/terra-slide-panel/tests/jest/SlidePanel.test.jsx
@@ -107,6 +107,15 @@ describe('When a SlidePanel is rendered', () => {
expect(wrapper).toMatchSnapshot();
});
+ it('should render a SlidePanel without main content if mainContent prop was not provided', () => {
+ const slidePanel = (
+
+ );
+ const wrapper = enzymeIntl.shallowWithIntl(slidePanel).dive();
+ const mainContent = wrapper.find('.main');
+ expect(mainContent.length).toBe(0);
+ });
+
it('should render a SlidePanel with panel content', () => {
const slidePanel = (
{
describe('Toggle the slide panel click', () => {
it('Opens panel and focuses on panel', () => {
browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-toggle');
- $('#test-toggle').click();
+ const disclosingButton = $('#test-toggle');
+ // the disclosing button should not have aria-expanded property yet
+ expect(disclosingButton.getAttribute('aria-expanded')).toBeFalsy();
+ disclosingButton.click();
$('#test-slide [aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
browser.pause(150);
expect($('[aria-label="Panel content area"]').isFocused()).toBeTruthy();
+ // the disclosing button should have aria-expanded property set to true
+ expect(disclosingButton.getAttribute('aria-expanded')).toBe('true');
// On Tab Press focuses on the button inside the panel
browser.keys(['Tab']);
@@ -80,17 +85,25 @@ Terra.describeViewports('Slide panel', ['large'], () => {
browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-toggle');
browser.keys(['Tab']);
- expect($('#test-toggle').isFocused()).toBeTruthy();
+ const disclosingButton = $('#test-toggle');
+ // the disclosing button should not have aria-expanded property yet
+ expect(disclosingButton.getAttribute('aria-expanded')).toBeFalsy();
+ expect(disclosingButton.isFocused()).toBeTruthy();
browser.keys(['Enter']);
$('#test-slide [aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
browser.pause(150);
browser.keys(['Tab']);
expect($('#focus-button').isFocused()).toBeTruthy();
+ // the disclosing button should have aria-expanded property set to true
+ expect(disclosingButton.getAttribute('aria-expanded')).toBe('true');
+
browser.keys(['Enter']);
$('#test-slide [aria-label="Panel content area"][aria-hidden="true"]').waitForExist();
expect($('#test-toggle').isFocused()).toBeTruthy();
+ // the disclosing button should have aria-expanded property set to false
+ expect(disclosingButton.getAttribute('aria-expanded')).toBe('false');
browser.pause(150);
@@ -199,28 +212,90 @@ Terra.describeViewports('Slide panel', ['large'], () => {
describe('Non-focusable element used to disclose slide panel', () => {
it('does not focus SVG when it is the disclosing node', () => {
browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-svg-toggle');
- $('#test-click-svg').moveTo();
- $('#test-click-svg').click();
+ const disclosingElement = $('#test-click-svg');
+ // the disclosing non-focusable element should not have aria-expanded property set
+ expect(disclosingElement.getAttribute('aria-expanded')).toBeFalsy();
+ $(disclosingElement).moveTo();
+ $(disclosingElement).click();
$('#test-slide [aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
browser.keys(['Tab']);
expect($('#focus-button').isFocused()).toBeTruthy();
+ // the disclosing non-focusable element should not have aria-expanded property set
+ expect(disclosingElement.getAttribute('aria-expanded')).toBeFalsy();
browser.keys(['Enter']);
expect($('[aria-label="Main content area"]').isFocused()).toBeTruthy();
- expect($('#test-click-svg').isFocused()).toBeFalsy();
+ expect($(disclosingElement).isFocused()).toBeFalsy();
});
it('focuses main node when disclosing node has undefined focus', () => {
browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-svg-toggle');
- $('#test-p-click').moveTo();
- $('#test-p-click').click();
+ const disclosingElement = $('#test-p-click');
+ // the disclosing non-focusable element should not have aria-expanded property set
+ expect(disclosingElement.getAttribute('aria-expanded')).toBeFalsy();
+ disclosingElement.moveTo();
+ disclosingElement.click();
$('#test-slide [aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
browser.keys(['Tab']);
expect($('#focus-button').isFocused()).toBeTruthy();
+ // the disclosing non-focusable element should not have aria-expanded property set
+ expect(disclosingElement.getAttribute('aria-expanded')).toBeFalsy();
browser.keys(['Enter']);
expect($('[aria-label="Main content area"]').isFocused()).toBeTruthy();
expect($('#test-click-svg').isFocused()).toBeFalsy();
});
});
+
+ describe('Slide panel with no mainContent prop passed', () => {
+ it('sets focus and aria-expanded props correctly if disclosing node is a regular button', () => {
+ browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-no-main-content');
+ const disclosureButton = $('#mainToggleBtn');
+ // the disclosing button should not have aria-expanded property set
+ expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
+ $(disclosureButton).moveTo();
+ $(disclosureButton).click();
+ $('[aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
+ browser.keys(['Tab']);
+ expect($('#panelToggleBtn').isFocused()).toBeTruthy();
+ // the disclosing button should have aria-expanded property set
+ expect(disclosureButton.getAttribute('aria-expanded')).toBe('true');
+ browser.keys(['Enter']);
+ expect(disclosureButton.isFocused()).toBeTruthy();
+ expect(disclosureButton.getAttribute('aria-expanded')).toBe('false');
+ });
+
+ it('sets focus and aria-expanded props correctly if disclosing node has unsupported role', () => {
+ browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-no-main-content');
+ const disclosureButton = $('#mainToggleBtnWithWrongRole');
+ // the disclosing button should not have aria-expanded property set
+ expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
+ $(disclosureButton).moveTo();
+ $(disclosureButton).click();
+ $('[aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
+ browser.keys(['Tab']);
+ expect($('#panelToggleBtn').isFocused()).toBeTruthy();
+ // the disclosing button should not have aria-expanded property set
+ expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
+ browser.keys(['Enter']);
+ expect(disclosureButton.isFocused()).toBeTruthy();
+ expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
+ });
+
+ it('sets focus and aria-expanded props correctly if disclosing node is not focusable', () => {
+ browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-no-main-content');
+ const disclosureElement = $('#mainToggleParagraph');
+ // the disclosing button should not have aria-expanded property set
+ expect(disclosureElement.getAttribute('aria-expanded')).toBeFalsy();
+ $(disclosureElement).moveTo();
+ $(disclosureElement).click();
+ $('[aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
+ browser.keys(['Tab']);
+ expect($('#panelToggleBtn').isFocused()).toBeTruthy();
+ // the disclosing button should not have aria-expanded property set
+ expect(disclosureElement.getAttribute('aria-expanded')).toBeFalsy();
+ browser.keys(['Enter']);
+ expect(disclosureElement.isFocused()).toBeFalsy();
+ });
+ });
});
From d0e0ace85093f37de0c0fafd6b0bad3a0dc635ff Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Mon, 25 Mar 2024 10:13:47 -0400
Subject: [PATCH 05/11] lint fix
---
.../SlidePanelNoMainContent.test.module.scss | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
index 26888cd3cf1..6fdc505a9af 100644
--- a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
+++ b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
@@ -3,26 +3,26 @@
position: relative;
}
- .panel-container {
- & > div:first-child {
- position: absolute;
- top: 0;
- bottom: 0;
- right: 0;
- left: 0;
- }
+ .panel-container > div:first-child {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 0;
}
.header-content {
background-color: #d3d3d3;
+
p {
width: auto;
display: inline-block;
margin: 0 !important;
}
- & > :not(:last-child){
- margin-right: 5px;
- }
+ }
+
+ .header-content > :not(:last-child){
+ margin-right: 5px;
}
.header-content h3 {
From dcea4f26d3d8c341f81269f4ef6b6d6d17eb1917 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Mon, 25 Mar 2024 10:29:26 -0400
Subject: [PATCH 06/11] changelog entry for terra-framework-docs added
---
packages/terra-framework-docs/CHANGELOG.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/terra-framework-docs/CHANGELOG.md b/packages/terra-framework-docs/CHANGELOG.md
index 39be7a91a18..871a72d36a3 100644
--- a/packages/terra-framework-docs/CHANGELOG.md
+++ b/packages/terra-framework-docs/CHANGELOG.md
@@ -5,6 +5,9 @@
* Changed
* Updated `terra-navigation-side-menu` example.
+* Added
+ * Added test example for `terra-slide-panel` with no `mainContent` prop.
+
## 1.75.0 - (March 19, 2024)
* Changed
@@ -13,7 +16,7 @@
## 1.74.0 - (March 14, 2024)
* Added
- * Added an example of a `compact-interactive-list` with no borders.
+ * Added an example for `terra-compact-interactive-list` with no borders.
* Changed
* Updated `terra-compact-interactive-list` documentation for `terra-menu` support.
From 4b61eb4b1f9f217a4961f054f9b9fb41f4594ea0 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Tue, 26 Mar 2024 13:10:08 -0400
Subject: [PATCH 07/11] removed role check, fixed example
---
.../placeholder-list/PlaceholderListItem.jsx | 1 -
packages/terra-slide-panel/src/SlidePanel.jsx | 36 ++-----------------
2 files changed, 2 insertions(+), 35 deletions(-)
diff --git a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
index e22aab74a19..54b0eed62de 100644
--- a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
+++ b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
@@ -24,7 +24,6 @@ const PlaceholderListItem = ({
className={classNames}
onClick={onSelect}
onKeyDown={keyDown}
- role="option"
>
{children}
diff --git a/packages/terra-slide-panel/src/SlidePanel.jsx b/packages/terra-slide-panel/src/SlidePanel.jsx
index 839ce5046a5..b66c765456f 100644
--- a/packages/terra-slide-panel/src/SlidePanel.jsx
+++ b/packages/terra-slide-panel/src/SlidePanel.jsx
@@ -85,32 +85,6 @@ const defaultProps = {
panelSize: 'small',
};
-/**
- * This method ensures that aria-expanded attribute is allowed with the node role to avoid accessibility violations.
- * More info on associated roles can be found here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded#associated_roles
- * @param {HTMLElement} node - a node to check
- * @returns true if node's role is compatible with aria-expanded attribute
- */
-const roleIsCompartible = (node) => {
- const role = node.getAttribute('role');
- return (
- role === 'application'
- || role === 'button'
- || role === 'checkbox'
- || role === 'combobox'
- || role === 'gridcell'
- || role === 'link'
- || role === 'listbox'
- || role === 'menuitem'
- || role === 'row'
- || role === 'rowheader'
- || role === 'tab'
- || role === 'treeitem'
- || role === null
- || role === undefined
- );
-};
-
class SlidePanel extends React.Component {
constructor(props) {
super(props);
@@ -131,10 +105,7 @@ class SlidePanel extends React.Component {
if (!this.props.isOpen && this.props.isOpen !== prevProps.isOpen) {
if (this.disclosingNode?.focus) {
// Return focus to the disclosing element
- if (this.disclosingNode.getAttribute('aria-expanded')) {
- // Set aria-expanded attribute to false for nodes that had that attribute only
- this.disclosingNode.setAttribute('aria-expanded', 'false');
- }
+ this.disclosingNode.setAttribute('aria-expanded', 'false');
this.disclosingNode.focus();
return;
}
@@ -156,10 +127,7 @@ class SlidePanel extends React.Component {
setDisclosingNode(node) {
if (node) {
- if (roleIsCompartible(node)) {
- // Set aria-expanded attribute to true for nodes with associated roles or no role only
- node.setAttribute('aria-expanded', 'true');
- }
+ node.setAttribute('aria-expanded', 'true');
this.disclosingNode = node;
}
}
From 0f70ca863a9222b410ef9df882baa18938af0745 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Tue, 26 Mar 2024 15:15:29 -0400
Subject: [PATCH 08/11] updated roles in example
---
.../doc/aggregator/common/placeholder-list/PlaceholderList.jsx | 2 +-
.../aggregator/common/placeholder-list/PlaceholderListItem.jsx | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderList.jsx b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderList.jsx
index 915cf7ddbbe..d8dae3a81c1 100644
--- a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderList.jsx
+++ b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderList.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import './PlaceholderList.module.scss';
/* eslint-disable */
const List = ({ children, isPadded }) => (
-
+
);
diff --git a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
index 54b0eed62de..9cf00af7f19 100644
--- a/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
+++ b/packages/terra-framework-docs/src/terra-dev-site/doc/aggregator/common/placeholder-list/PlaceholderListItem.jsx
@@ -24,6 +24,7 @@ const PlaceholderListItem = ({
className={classNames}
onClick={onSelect}
onKeyDown={keyDown}
+ role="tab"
>
{children}
From fb141d76ff591a6048c843882f35260a44c6df27 Mon Sep 17 00:00:00 2001
From: Alla Doroshkevych
Date: Tue, 26 Mar 2024 15:39:57 -0400
Subject: [PATCH 09/11] removed unnecessary test
---
.../tests/wdio/slide-panel-spec.js | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js b/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
index fff46913b20..77228ba8e37 100644
--- a/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
+++ b/packages/terra-slide-panel/tests/wdio/slide-panel-spec.js
@@ -265,23 +265,6 @@ Terra.describeViewports('Slide panel', ['large'], () => {
expect(disclosureButton.getAttribute('aria-expanded')).toBe('false');
});
- it('sets focus and aria-expanded props correctly if disclosing node has unsupported role', () => {
- browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-no-main-content');
- const disclosureButton = $('#mainToggleBtnWithWrongRole');
- // the disclosing button should not have aria-expanded property set
- expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
- $(disclosureButton).moveTo();
- $(disclosureButton).click();
- $('[aria-label="Panel content area"][aria-hidden="false"]').waitForExist();
- browser.keys(['Tab']);
- expect($('#panelToggleBtn').isFocused()).toBeTruthy();
- // the disclosing button should not have aria-expanded property set
- expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
- browser.keys(['Enter']);
- expect(disclosureButton.isFocused()).toBeTruthy();
- expect(disclosureButton.getAttribute('aria-expanded')).toBeFalsy();
- });
-
it('sets focus and aria-expanded props correctly if disclosing node is not focusable', () => {
browser.url('/raw/tests/cerner-terra-framework-docs/slide-panel/slide-panel-no-main-content');
const disclosureElement = $('#mainToggleParagraph');
From adba09e8ade9fac38fb5ad0e34cbb83c0e1c8219 Mon Sep 17 00:00:00 2001
From: Saad Adnan <38024451+sdadn@users.noreply.github.com>
Date: Tue, 26 Mar 2024 16:32:48 -0500
Subject: [PATCH 10/11] Update SlidePanelNoMainContent.test.module.scss
---
.../test/slide-panel/SlidePanelNoMainContent.test.module.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
index 6fdc505a9af..01d0ec03265 100644
--- a/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
+++ b/packages/terra-framework-docs/src/terra-dev-site/test/slide-panel/SlidePanelNoMainContent.test.module.scss
@@ -38,4 +38,4 @@
.custom-button {
display: inline-block;
}
- }
\ No newline at end of file
+ }
From 91a669cd9fece23af09f713d6e90df04b9b624aa Mon Sep 17 00:00:00 2001
From: Saad Adnan <38024451+sdadn@users.noreply.github.com>
Date: Tue, 26 Mar 2024 16:33:13 -0500
Subject: [PATCH 11/11] Update CHANGELOG.md
---
packages/terra-slide-panel/CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/terra-slide-panel/CHANGELOG.md b/packages/terra-slide-panel/CHANGELOG.md
index 7af7307f7ec..586ba336776 100644
--- a/packages/terra-slide-panel/CHANGELOG.md
+++ b/packages/terra-slide-panel/CHANGELOG.md
@@ -3,7 +3,7 @@
## Unreleased
* Changed
- * Updated capturing the disclosing node to accommodate for cases with no `mainContent`
+ * Updated capturing the disclosing node to accommodate for cases with no `mainContent`.
## 3.47.0 - (December 18, 2023)