Skip to content

Commit 7a4003a

Browse files
authored
#2818 Palette category does not expand when activated via Screen Reader (#2819)
Signed-off-by: CTomlyn <[email protected]>
1 parent 683294b commit 7a4003a

File tree

4 files changed

+52
-43
lines changed

4 files changed

+52
-43
lines changed

canvas_modules/common-canvas/src/common-canvas/keyboard-utils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const BACKSPACE_KEY = "Backspace";
2727
const DELETE_KEY = "Delete";
2828
const SPACE_KEY = "Space";
2929

30+
const NO_BREAK_SPACE_CHAR_KEY = "\u00A0"; // Can be returned in short cuts for screen readers
3031
const SPACE_CHAR_KEY = " ";
3132
const COMMA_CHAR_KEY = ",";
3233

@@ -481,7 +482,7 @@ export default class KeyboardUtils {
481482

482483
// key property can sometimes be set to "Space" (SPACE_KEY) in tests.
483484
static isSpaceKey(evt) {
484-
return evt.key === SPACE_CHAR_KEY || evt.key === SPACE_KEY;
485+
return evt.key === SPACE_CHAR_KEY || evt.key === NO_BREAK_SPACE_CHAR_KEY || evt.key === SPACE_KEY;
485486
}
486487

487488
// Returns true if either the 'Command Key' on Mac or

canvas_modules/common-canvas/src/palette/palette-content-list-item.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class PaletteContentListItem extends React.Component {
8686
onKeyDown(evt) {
8787
if (KeyboardUtils.createAutoNode(evt)) {
8888
this.createAutoNode(true);
89+
evt.stopPropagation(); // Stop key event propagating and closing the category.
8990

9091
} else if (KeyboardUtils.createAutoNodeNoLink(evt)) {
9192
this.createAutoNode(false); // false indicates no links are required
@@ -107,7 +108,9 @@ class PaletteContentListItem extends React.Component {
107108
}
108109

109110
onDoubleClick() {
110-
this.createAutoNode(true);
111+
if (!this.props.allowClickToAdd) {
112+
this.createAutoNode(true);
113+
}
111114
}
112115

113116
onClick() {

canvas_modules/common-canvas/src/palette/palette-flyout-content-category.jsx

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class PaletteFlyoutContentCategory extends React.Component {
3131
this.onMouseOver = this.onMouseOver.bind(this);
3232
this.onMouseLeave = this.onMouseLeave.bind(this);
3333
this.onFocus = this.onFocus.bind(this);
34-
this.categoryClicked = this.categoryClicked.bind(this);
35-
this.categoryKeyPressed = this.categoryKeyPressed.bind(this);
36-
this.setPaletteCategory = this.setPaletteCategory.bind(this);
34+
this.onKeyDownCategory = this.onKeyDownCategory.bind(this);
35+
this.onHeadingClick = this.onHeadingClick.bind(this);
36+
this.getTitleObj = this.getTitleObj.bind(this);
3737
}
3838

3939
onMouseOver(evt) {
@@ -48,6 +48,36 @@ class PaletteFlyoutContentCategory extends React.Component {
4848
this.displayTip(evt);
4949
}
5050

51+
onKeyDownCategory(evt) {
52+
if (KeyboardUtils.openCategory(evt)) {
53+
this.onHeadingClick();
54+
CanvasUtils.stopPropagationAndPreventDefault(evt);
55+
56+
} else if (this.props.category.is_open &&
57+
KeyboardUtils.fromCategoryToFirstNode(evt)) {
58+
this.pclRef.current.setFirstNode();
59+
CanvasUtils.stopPropagationAndPreventDefault(evt);
60+
61+
} else if (KeyboardUtils.tabFocusOutOfPalette(evt) &&
62+
this.props.tabOut) {
63+
this.props.tabOut(evt);
64+
}
65+
}
66+
67+
// Handles a click on the category heading area. This is called from the Accordion
68+
// Item when:
69+
// * the user clicks on a header AND
70+
// * when the user presses the appropriate keyboard shortcut
71+
// Additionally, it's called from onKeyDownCategory when the user presses space
72+
// or return.
73+
onHeadingClick() {
74+
if (this.props.category.is_open) {
75+
this.props.canvasController.closePaletteCategory(this.props.category.id);
76+
} else {
77+
this.props.canvasController.openPaletteCategory(this.props.category.id);
78+
}
79+
}
80+
5181
getInlineLoadingRenderCategory() {
5282
// TODO - This loading functionality should be replaced with a skeleton
5383
// graphic to indicate the category is loading instead of using the
@@ -81,21 +111,17 @@ class PaletteFlyoutContentCategory extends React.Component {
81111
return content;
82112
}
83113

84-
setPaletteCategory(isOpen) {
85-
if (isOpen) {
86-
this.props.canvasController.closePaletteCategory(this.props.category.id);
87-
} else {
88-
this.props.canvasController.openPaletteCategory(this.props.category.id);
89-
}
90-
}
91-
92114
// Returns the category object for a regular category.
93115
getRenderCategory() {
94116
const titleObj = this.getTitleObj();
95117
const content = this.getContent();
96118
return (
97-
<AccordionItem title={titleObj} open={this.props.category.is_open}
98-
onKeyDown={this.categoryKeyPressed} onFocus={this.onFocus}
119+
<AccordionItem
120+
title={titleObj}
121+
open={this.props.category.is_open}
122+
onKeyDown={this.onKeyDownCategory}
123+
onFocus={this.onFocus}
124+
onHeadingClick={this.onHeadingClick}
99125
>
100126
{content}
101127
</AccordionItem>
@@ -107,19 +133,20 @@ class PaletteFlyoutContentCategory extends React.Component {
107133
const itemImage = this.getItemImage();
108134
const itemText = this.getItemText();
109135
this.catRef = React.createRef();
136+
110137
return (
111138
<div className="palette-flyout-category"
112139
ref={this.catRef}
113140
data-id={get(this.props.category, "id", "")}
114-
onClick={this.categoryClicked}
115141
value={this.props.category.label}
116142
onMouseOver={this.onMouseOver}
117143
onMouseLeave={this.onMouseLeave}
118144
>
119145
<div className="palette-flyout-category-item" tabIndex={-1}>
120146
{itemImage}
121147
{itemText}
122-
</div></div>
148+
</div>
149+
</div>
123150
);
124151
}
125152

@@ -218,32 +245,6 @@ class PaletteFlyoutContentCategory extends React.Component {
218245

219246
}
220247

221-
categoryClicked(evt) {
222-
// Stopping event propagation prevents an extra refresh of the node icons when
223-
// a category is opened.
224-
evt.stopPropagation();
225-
226-
this.setPaletteCategory(this.props.category.is_open);
227-
}
228-
229-
categoryKeyPressed(evt) {
230-
if (evt.target.className === "cds--accordion__heading") {
231-
if (KeyboardUtils.openCategory(evt)) {
232-
this.setPaletteCategory(this.props.category.is_open);
233-
CanvasUtils.stopPropagationAndPreventDefault(evt);
234-
235-
} else if (this.props.category.is_open &&
236-
KeyboardUtils.fromCategoryToFirstNode(evt)) {
237-
this.pclRef.current.setFirstNode();
238-
CanvasUtils.stopPropagationAndPreventDefault(evt);
239-
240-
} else if (KeyboardUtils.tabFocusOutOfPalette(evt) &&
241-
this.props.tabOut) {
242-
this.props.tabOut(evt);
243-
}
244-
}
245-
}
246-
247248
render() {
248249
return this.props.category.loading_text
249250
? this.getInlineLoadingRenderCategory()

canvas_modules/harness/cypress/support/canvas/palette-cmds.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,12 @@ Cypress.Commands.add("tabToCategory", (categoryLabel) => {
155155
.focus();
156156
});
157157

158+
// Simulates a press of the space bar on a category. We need to send the key event to the
159+
// grandparent of the category element.
158160
Cypress.Commands.add("pressSpaceOnCategory", (categoryLabel) => {
159161
cy.findCategory(categoryLabel)
162+
.parent()
163+
.parent()
160164
.type(" ");
161165
});
162166

0 commit comments

Comments
 (0)