@pingux/astro 2.200.1-alpha.0 → 2.200.3-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/AccordionGridItem/AccordionGridItemHeader.js +2 -1
- package/lib/cjs/components/AccordionItem/AccordionItem.js +4 -2
- package/lib/cjs/components/ColorField/ColorField.test.js +13 -9
- package/lib/cjs/components/ColorField/ColorFieldPreviewButton.js +5 -2
- package/lib/cjs/components/DataTable/DataTable.js +8 -2
- package/lib/cjs/components/EnvironmentBreadcrumb/EnvironmentBreadcrumb.js +3 -2
- package/lib/cjs/components/Icon/IconDefault.js +15 -0
- package/lib/cjs/components/LinkSelectField/LinkSelectField.js +3 -2
- package/lib/cjs/components/ListView/ListViewExpandableItem.js +3 -2
- package/lib/cjs/components/MultivaluesField/CondensedMultivaluesField.js +8 -7
- package/lib/cjs/components/MultivaluesField/DefaultMultivaluesField.js +5 -5
- package/lib/cjs/components/MultivaluesField/MultivaluesField.test.js +24 -0
- package/lib/cjs/components/NavBarSection/NavBarItemBody.test.js +1 -0
- package/lib/cjs/components/NavBarSection/NavBarItemHeader.js +3 -2
- package/lib/cjs/components/NavSideBar/NavSideBarSectionHeader.js +2 -2
- package/lib/cjs/components/NavigationHeader/HeaderAccountMenu.js +2 -1
- package/lib/cjs/components/SelectFieldBase/SelectFieldBase.js +3 -2
- package/lib/cjs/components/SelectFieldBase/SelectFieldBase.test.js +20 -1
- package/lib/cjs/components/TabPicker/TabPicker.js +3 -2
- package/lib/cjs/recipes/MultipagePopup.stories.js +3 -2
- package/lib/cjs/styles/templates/Nav/HeaderBar.js +3 -2
- package/lib/cjs/styles/themes/next-gen/variants/input.js +1 -1
- package/lib/cjs/utils/testUtils/universalFormSubmitTest.js +7 -17
- package/lib/components/AccordionGridItem/AccordionGridItemHeader.js +2 -1
- package/lib/components/AccordionItem/AccordionItem.js +4 -2
- package/lib/components/ColorField/ColorField.test.js +13 -9
- package/lib/components/ColorField/ColorFieldPreviewButton.js +5 -2
- package/lib/components/DataTable/DataTable.js +8 -2
- package/lib/components/EnvironmentBreadcrumb/EnvironmentBreadcrumb.js +3 -2
- package/lib/components/Icon/IconDefault.js +15 -0
- package/lib/components/LinkSelectField/LinkSelectField.js +3 -2
- package/lib/components/ListView/ListViewExpandableItem.js +3 -2
- package/lib/components/MultivaluesField/CondensedMultivaluesField.js +8 -7
- package/lib/components/MultivaluesField/DefaultMultivaluesField.js +5 -5
- package/lib/components/MultivaluesField/MultivaluesField.test.js +24 -0
- package/lib/components/NavBarSection/NavBarItemBody.test.js +1 -0
- package/lib/components/NavBarSection/NavBarItemHeader.js +3 -2
- package/lib/components/NavSideBar/NavSideBarSectionHeader.js +2 -2
- package/lib/components/NavigationHeader/HeaderAccountMenu.js +2 -1
- package/lib/components/SelectFieldBase/SelectFieldBase.js +3 -2
- package/lib/components/SelectFieldBase/SelectFieldBase.test.js +20 -1
- package/lib/components/TabPicker/TabPicker.js +3 -2
- package/lib/recipes/MultipagePopup.stories.js +3 -2
- package/lib/styles/templates/Nav/HeaderBar.js +3 -2
- package/lib/styles/themes/next-gen/variants/input.js +1 -1
- package/lib/utils/testUtils/universalFormSubmitTest.js +7 -17
- package/package.json +1 -1
|
@@ -117,8 +117,9 @@ var AccordionGridItemHeader = /*#__PURE__*/(0, _react.forwardRef)(function (prop
|
|
|
117
117
|
}, isOnyx && {
|
|
118
118
|
size: 'sm'
|
|
119
119
|
}, {
|
|
120
|
+
"aria-hidden": "true",
|
|
120
121
|
title: {
|
|
121
|
-
name:
|
|
122
|
+
name: ''
|
|
122
123
|
}
|
|
123
124
|
})))));
|
|
124
125
|
});
|
|
@@ -102,13 +102,15 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
102
102
|
sx: accordionHoveredState
|
|
103
103
|
}, item.props.label), (0, _react2.jsx)(_index.Box, {
|
|
104
104
|
as: "span",
|
|
105
|
-
ml: accordionItemMarginLeft
|
|
105
|
+
ml: accordionItemMarginLeft,
|
|
106
|
+
role: "presentation"
|
|
106
107
|
}, (0, _react2.jsx)(_index.Icon, {
|
|
107
108
|
color: "font.base",
|
|
108
109
|
icon: isOpen ? MenuUp : MenuDown,
|
|
109
110
|
size: "sm",
|
|
111
|
+
"aria-hidden": "true",
|
|
110
112
|
title: {
|
|
111
|
-
name:
|
|
113
|
+
name: ''
|
|
112
114
|
}
|
|
113
115
|
}))), ((_item$props$slots = item.props.slots) === null || _item$props$slots === void 0 ? void 0 : _item$props$slots.postHeading) && ((_item$props$slots2 = item.props.slots) === null || _item$props$slots2 === void 0 ? void 0 : _item$props$slots2.postHeading)), isOpen && (0, _react2.jsx)(_index.Box, (0, _extends2["default"])({
|
|
114
116
|
variant: "accordion.body"
|
|
@@ -136,8 +136,8 @@ test('renders detailed button preview mode correctly', function () {
|
|
|
136
136
|
expect(_testWrapper.screen.getByText(testLabel)).toBeInTheDocument();
|
|
137
137
|
expect(_testWrapper.screen.getByText(testColor1.toLocaleUpperCase())).toBeInTheDocument();
|
|
138
138
|
});
|
|
139
|
-
test('renders MenuUp / MenuDown icon
|
|
140
|
-
var button;
|
|
139
|
+
test('renders MenuUp / MenuDown icon with aria-hidden="true" so screen readers skip it', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
140
|
+
var button, closedIcon, openIcon;
|
|
141
141
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
142
142
|
while (1) switch (_context3.prev = _context3.next) {
|
|
143
143
|
case 0:
|
|
@@ -145,16 +145,20 @@ test('renders MenuUp / MenuDown icon correctly', /*#__PURE__*/(0, _asyncToGenera
|
|
|
145
145
|
mode: 'detailed-button-preview',
|
|
146
146
|
value: testColor1
|
|
147
147
|
});
|
|
148
|
-
button = _testWrapper.screen.getByRole('button');
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
expect(
|
|
148
|
+
button = _testWrapper.screen.getByRole('button'); // Before opening: the closed-state icon (MenuDown) is rendered inside a
|
|
149
|
+
// role="presentation" box and must carry aria-hidden="true".
|
|
150
|
+
closedIcon = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
151
|
+
expect(closedIcon).toBeInTheDocument();
|
|
152
|
+
expect(closedIcon).toHaveAttribute('aria-hidden', 'true');
|
|
153
153
|
_context3.next = 7;
|
|
154
154
|
return _userEvent["default"].click(button);
|
|
155
155
|
case 7:
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
// After opening: the open-state icon (MenuUp) replaces MenuDown and must also
|
|
157
|
+
// carry aria-hidden="true".
|
|
158
|
+
openIcon = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
159
|
+
expect(openIcon).toBeInTheDocument();
|
|
160
|
+
expect(openIcon).toHaveAttribute('aria-hidden', 'true');
|
|
161
|
+
case 10:
|
|
158
162
|
case "end":
|
|
159
163
|
return _context3.stop();
|
|
160
164
|
}
|
|
@@ -52,15 +52,18 @@ var ColorFieldPreviewButton = /*#__PURE__*/(0, _react.forwardRef)(function (prop
|
|
|
52
52
|
sx: {
|
|
53
53
|
ml: 'auto'
|
|
54
54
|
},
|
|
55
|
-
flexGrow: "1"
|
|
55
|
+
flexGrow: "1",
|
|
56
|
+
role: "presentation"
|
|
56
57
|
}, (0, _react2.jsx)(_index.Icon, (0, _extends2["default"])({
|
|
57
58
|
ml: "auto",
|
|
58
59
|
title: {
|
|
59
|
-
name:
|
|
60
|
+
name: ''
|
|
60
61
|
},
|
|
61
62
|
icon: isOpen ? MenuUp : MenuDown
|
|
62
63
|
}, isOnyx && {
|
|
63
64
|
size: 'sm'
|
|
65
|
+
}, {
|
|
66
|
+
"aria-hidden": "true"
|
|
64
67
|
})))));
|
|
65
68
|
});
|
|
66
69
|
var _default = exports["default"] = ColorFieldPreviewButton;
|
|
@@ -294,18 +294,24 @@ var TableColumnHeader = function TableColumnHeader(props) {
|
|
|
294
294
|
columnHeaderProps = _useTableColumnHeader.columnHeaderProps;
|
|
295
295
|
var columnProps = column.props;
|
|
296
296
|
var iconSize = isOnyx ? 16 : 24;
|
|
297
|
+
// Sort-direction icons are purely presentational; aria-sort on the <th> conveys
|
|
298
|
+
// sort state to screen readers. Pass aria-hidden="true" to remove the SVG from
|
|
299
|
+
// the accessibility tree, and title={{ name: '' }} to suppress the browser-native
|
|
300
|
+
// hover tooltip that the MDI icon package would otherwise generate.
|
|
297
301
|
var arrowIcon = ((_state$sortDescriptor = state.sortDescriptor) === null || _state$sortDescriptor === void 0 ? void 0 : _state$sortDescriptor.direction) === 'ascending' && column.key === ((_state$sortDescriptor2 = state.sortDescriptor) === null || _state$sortDescriptor2 === void 0 ? void 0 : _state$sortDescriptor2.column) ? (0, _react2.jsx)(_index.Icon, {
|
|
298
302
|
size: iconSize,
|
|
299
303
|
icon: Ascending,
|
|
304
|
+
"aria-hidden": "true",
|
|
300
305
|
title: {
|
|
301
|
-
name: '
|
|
306
|
+
name: ''
|
|
302
307
|
}
|
|
303
308
|
}) : (0, _react2.jsx)(_index.Icon, {
|
|
304
309
|
size: iconSize,
|
|
305
310
|
icon: Descending,
|
|
306
311
|
color: "active",
|
|
312
|
+
"aria-hidden": "true",
|
|
307
313
|
title: {
|
|
308
|
-
name: '
|
|
314
|
+
name: ''
|
|
309
315
|
}
|
|
310
316
|
});
|
|
311
317
|
var allProps = [columnHeaderProps];
|
|
@@ -260,10 +260,11 @@ var EnvironmentBreadcrumb = /*#__PURE__*/(0, _react.forwardRef)(function (props,
|
|
|
260
260
|
}), selectedItem, (0, _react2.jsx)(_index.Icon, {
|
|
261
261
|
icon: popoverState.isOpen ? MenuUp : MenuDown,
|
|
262
262
|
title: {
|
|
263
|
-
name:
|
|
263
|
+
name: ''
|
|
264
264
|
},
|
|
265
265
|
size: "xs",
|
|
266
|
-
ml: "xs"
|
|
266
|
+
ml: "xs",
|
|
267
|
+
"aria-hidden": "true"
|
|
267
268
|
})), (0, _react2.jsx)(_index.PopoverContainer, (0, _extends2["default"])({}, overlayProps, positionProps, (0, _reactAria.mergeProps)(overlayProps, positionProps, popoverProps), {
|
|
268
269
|
ref: overlayRef,
|
|
269
270
|
isOpen: popoverState.isOpen,
|
|
@@ -44,6 +44,21 @@ var IconDefault = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
|
44
44
|
sizeProps = _useTShirtSize.sizeProps;
|
|
45
45
|
var defaultIconColor = theme.defaultIconColor,
|
|
46
46
|
isOnyx = theme.themeState.isOnyx;
|
|
47
|
+
|
|
48
|
+
// `role="img"` below is intentional for non-hidden icons: it exposes the icon
|
|
49
|
+
// to the accessibility tree with a meaningful name derived from `resolvedTitle`.
|
|
50
|
+
//
|
|
51
|
+
// Callers that render a purely presentational icon (e.g. a decorative arrow)
|
|
52
|
+
// must pass BOTH props together:
|
|
53
|
+
// aria-hidden="true" — removes the element from the accessibility tree so
|
|
54
|
+
// screen readers skip it entirely.
|
|
55
|
+
// title={{ name: '' }} — renders an empty SVG <title> element, suppressing
|
|
56
|
+
// the browser-native tooltip that the MDI icon package
|
|
57
|
+
// would otherwise produce from its auto-generated UUID
|
|
58
|
+
// title string.
|
|
59
|
+
// `aria-hidden` alone is sufficient for screen readers, but without the empty
|
|
60
|
+
// title prop the SVG <title> can still surface as a tooltip on hover in some
|
|
61
|
+
// browsers, so both props are needed for a complete presentational treatment.
|
|
47
62
|
var resolvedTitle = title !== null && title !== void 0 ? title : (0, _typeof2["default"])(IconComponent) === 'object' && 'type' in IconComponent ? {
|
|
48
63
|
name: IconComponent.type.name
|
|
49
64
|
} : '';
|
|
@@ -83,7 +83,7 @@ var LinkSelectField = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref)
|
|
|
83
83
|
variant: "loader.withinInput"
|
|
84
84
|
}), (0, _react2.jsx)(_.Box, {
|
|
85
85
|
as: "span",
|
|
86
|
-
|
|
86
|
+
role: "presentation",
|
|
87
87
|
variant: "forms.select.arrow"
|
|
88
88
|
}, (0, _react2.jsx)(_.Icon, (0, _extends2["default"])({
|
|
89
89
|
icon: MenuDown,
|
|
@@ -91,7 +91,8 @@ var LinkSelectField = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref)
|
|
|
91
91
|
name: ''
|
|
92
92
|
},
|
|
93
93
|
color: isOnyx ? 'font.link' : 'active',
|
|
94
|
-
size: linkSelectFieldIcon
|
|
94
|
+
size: linkSelectFieldIcon,
|
|
95
|
+
"aria-hidden": "true"
|
|
95
96
|
}, iconProps, {
|
|
96
97
|
sx: _objectSpread({
|
|
97
98
|
transform: state.isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
@@ -83,8 +83,9 @@ var ListViewExpandableItem = function ListViewExpandableItem(props) {
|
|
|
83
83
|
icon: isExpanded ? MenuUp : MenuDown,
|
|
84
84
|
variant: "listViewItem.expandIcon",
|
|
85
85
|
title: {
|
|
86
|
-
name:
|
|
87
|
-
}
|
|
86
|
+
name: ''
|
|
87
|
+
},
|
|
88
|
+
"aria-hidden": "true"
|
|
88
89
|
}, isOnyx && {
|
|
89
90
|
size: 'sm'
|
|
90
91
|
})))), (0, _react2.jsx)(_index.Box, expandableItemState.gridCellProps, isExpanded && (0, _react2.jsx)(_ListViewFocusWrapper["default"], {
|
|
@@ -394,14 +394,15 @@ var CondensedMultivaluesField = /*#__PURE__*/(0, _react.forwardRef)(function (pr
|
|
|
394
394
|
sx: {
|
|
395
395
|
border: 'none'
|
|
396
396
|
},
|
|
397
|
-
|
|
398
|
-
name: ''
|
|
399
|
-
}
|
|
397
|
+
"aria-label": isOpen ? 'Close menu' : 'Open menu'
|
|
400
398
|
}, (0, _react2.jsx)(_.Icon, (0, _extends2["default"])({
|
|
401
399
|
icon: isOpen ? MenuUp : MenuDown
|
|
402
400
|
}, isOnyx && {
|
|
403
401
|
size: 'sm'
|
|
404
402
|
}, {
|
|
403
|
+
title: {
|
|
404
|
+
name: ''
|
|
405
|
+
},
|
|
405
406
|
"aria-hidden": "true"
|
|
406
407
|
}))));
|
|
407
408
|
return (0, _react2.jsx)(_MultivaluesContext.MultivaluesContext.Provider, {
|
|
@@ -519,10 +520,10 @@ CondensedMultivaluesField.propTypes = _objectSpread(_objectSpread(_objectSpread(
|
|
|
519
520
|
*/
|
|
520
521
|
onKeyDown: _propTypes["default"].func,
|
|
521
522
|
/**
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
523
|
+
* Handler that is called when a key is released.
|
|
524
|
+
*
|
|
525
|
+
* `(e: KeyboardEvent) => void`
|
|
526
|
+
*/
|
|
526
527
|
onKeyUp: _propTypes["default"].func,
|
|
527
528
|
/**
|
|
528
529
|
* Method that is called when the open state of the menu changes.
|
|
@@ -44,8 +44,8 @@ var _isIterable = require("../../utils/devUtils/props/isIterable");
|
|
|
44
44
|
var _ariaAttributes = require("../../utils/docUtils/ariaAttributes");
|
|
45
45
|
var _fieldAttributes = require("../../utils/docUtils/fieldAttributes");
|
|
46
46
|
var _statusProp = require("../../utils/docUtils/statusProp");
|
|
47
|
-
var _BadgeLabelTooltip = _interopRequireDefault(require("./BadgeLabelTooltip"));
|
|
48
47
|
var _ListBox = _interopRequireDefault(require("../ListBox"));
|
|
48
|
+
var _BadgeLabelTooltip = _interopRequireDefault(require("./BadgeLabelTooltip"));
|
|
49
49
|
var _react2 = require("@emotion/react");
|
|
50
50
|
var _excluded = ["items"],
|
|
51
51
|
_excluded2 = ["defaultSelectedKeys", "direction", "disabledKeys", "containerProps", "hasAutoFocus", "hasNoStatusIndicator", "helperText", "inputProps", "isDisabled", "isFilteringDisabled", "isNotFlippable", "isReadOnly", "isRequired", "label", "loadingState", "mode", "onBlur", "onFocus", "onInputChange", "onKeyDown", "onKeyUp", "onLoadMore", "onLoadPrev", "onOpenChange", "onSelectionChange", "placeholder", "readOnlyKeys", "selectedKeys", "scrollBoxProps", "status"];
|
|
@@ -617,10 +617,10 @@ DefaultMultivaluesField.propTypes = _objectSpread(_objectSpread(_objectSpread({
|
|
|
617
617
|
*/
|
|
618
618
|
onKeyDown: _propTypes["default"].func,
|
|
619
619
|
/**
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
620
|
+
* Handler that is called when a key is released.
|
|
621
|
+
*
|
|
622
|
+
* `(e: KeyboardEvent) => void`
|
|
623
|
+
*/
|
|
624
624
|
onKeyUp: _propTypes["default"].func,
|
|
625
625
|
/**
|
|
626
626
|
* Method that is called when the open state of the menu changes.
|
|
@@ -2060,4 +2060,28 @@ test('hovering delete button does not show tooltip for long label badge', functi
|
|
|
2060
2060
|
testValue: items[0].name,
|
|
2061
2061
|
testLabel: defaultProps.label,
|
|
2062
2062
|
componentType: 'MultivaluesField'
|
|
2063
|
+
});
|
|
2064
|
+
test('in condensed mode, arrow icon SVG has aria-hidden="true" to be hidden from screen readers', function () {
|
|
2065
|
+
getComponent({
|
|
2066
|
+
mode: 'condensed'
|
|
2067
|
+
});
|
|
2068
|
+
// The presentational arrow icon (MenuDown/MenuUp) in the condensed mode trigger
|
|
2069
|
+
// button receives aria-hidden="true" via props, making it invisible to screen
|
|
2070
|
+
// readers. Scope the query to the trigger button (tabIndex=-1) to avoid
|
|
2071
|
+
// accidentally matching any other aria-hidden SVG added in future.
|
|
2072
|
+
var arrowIconSvg = document.querySelector('button[tabindex="-1"] svg[aria-hidden="true"]');
|
|
2073
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
2074
|
+
expect(arrowIconSvg).toHaveAttribute('aria-hidden', 'true');
|
|
2075
|
+
});
|
|
2076
|
+
test('in condensed mode, arrow icon SVG has an empty title element so no tooltip is shown', function () {
|
|
2077
|
+
getComponent({
|
|
2078
|
+
mode: 'condensed'
|
|
2079
|
+
});
|
|
2080
|
+
// title={{ name: '' }} renders an empty SVG <title> element, suppressing
|
|
2081
|
+
// the browser-native tooltip that would otherwise appear on hover.
|
|
2082
|
+
var arrowIconSvg = document.querySelector('button[tabindex="-1"] svg[aria-hidden="true"]');
|
|
2083
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
2084
|
+
var titleElement = arrowIconSvg.querySelector('title');
|
|
2085
|
+
expect(titleElement).toBeInTheDocument();
|
|
2086
|
+
expect(titleElement).toHaveTextContent('');
|
|
2063
2087
|
});
|
|
@@ -14,6 +14,7 @@ var SUBTITLE = 'subtitle';
|
|
|
14
14
|
var TEXT = 'text';
|
|
15
15
|
var data = [{
|
|
16
16
|
key: 'Dashboard',
|
|
17
|
+
heading: 'Dashboard',
|
|
17
18
|
children: ['Users', 'Group', 'Populations', 'Attributes', 'Roles', 'Dashboard Unique']
|
|
18
19
|
}];
|
|
19
20
|
var NavBarWithItemBody = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
|
|
@@ -104,8 +104,9 @@ var NavBarSectionItemHeader = function NavBarSectionItemHeader(_ref2) {
|
|
|
104
104
|
fill: getIconColor()
|
|
105
105
|
},
|
|
106
106
|
title: {
|
|
107
|
-
name:
|
|
108
|
-
}
|
|
107
|
+
name: ''
|
|
108
|
+
},
|
|
109
|
+
"aria-hidden": "true"
|
|
109
110
|
})));
|
|
110
111
|
};
|
|
111
112
|
var NavBarPrimaryItemHeader = function NavBarPrimaryItemHeader(_ref3) {
|
|
@@ -92,9 +92,9 @@ var NavSideBarSectionHeader = function NavSideBarSectionHeader(props) {
|
|
|
92
92
|
variant: variant,
|
|
93
93
|
mr: "0",
|
|
94
94
|
title: {
|
|
95
|
-
name:
|
|
95
|
+
name: ''
|
|
96
96
|
},
|
|
97
|
-
"aria-
|
|
97
|
+
"aria-hidden": "true"
|
|
98
98
|
}))));
|
|
99
99
|
};
|
|
100
100
|
var _default = exports["default"] = NavSideBarSectionHeader;
|
|
@@ -84,14 +84,15 @@ var SelectFieldBase = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref)
|
|
|
84
84
|
};
|
|
85
85
|
var buttonRendered = !(hasClearButton && state.selectedKey) && (0, _react2.jsx)(_.Box, {
|
|
86
86
|
as: "span",
|
|
87
|
-
|
|
87
|
+
role: "presentation",
|
|
88
88
|
variant: "forms.select.arrow"
|
|
89
89
|
}, (0, _react2.jsx)(_.Icon, {
|
|
90
90
|
icon: state.isOpen ? MenuUp : MenuDown,
|
|
91
91
|
title: {
|
|
92
92
|
name: ''
|
|
93
93
|
},
|
|
94
|
-
size: isOnyx ? 'sm' : 'md'
|
|
94
|
+
size: isOnyx ? 'sm' : 'md',
|
|
95
|
+
"aria-hidden": "true"
|
|
95
96
|
}));
|
|
96
97
|
var clearButton = hasClearButton && state.selectedKey && (0, _react2.jsx)(_.IconButton, (0, _extends2["default"])({
|
|
97
98
|
tabIndex: 0,
|
|
@@ -640,4 +640,23 @@ test('should have call onClear function', /*#__PURE__*/(0, _asyncToGenerator2["d
|
|
|
640
640
|
return _context13.stop();
|
|
641
641
|
}
|
|
642
642
|
}, _callee13);
|
|
643
|
-
})));
|
|
643
|
+
})));
|
|
644
|
+
test('arrow icon SVG has aria-hidden="true" to be hidden from screen readers', function () {
|
|
645
|
+
getComponent();
|
|
646
|
+
// The presentational arrow icon (MenuDown/MenuUp) is rendered inside a
|
|
647
|
+
// role="presentation" span. The Icon component renders as an SVG element
|
|
648
|
+
// and receives aria-hidden="true" via props, making it invisible to screen readers.
|
|
649
|
+
var arrowIconSvg = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
650
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
651
|
+
expect(arrowIconSvg).toHaveAttribute('aria-hidden', 'true');
|
|
652
|
+
});
|
|
653
|
+
test('arrow icon SVG has an empty title element so no tooltip is shown', function () {
|
|
654
|
+
getComponent();
|
|
655
|
+
// title={{ name: '' }} renders an empty SVG <title> element, suppressing
|
|
656
|
+
// the browser-native tooltip that would otherwise appear on hover.
|
|
657
|
+
var arrowIconSvg = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
658
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
659
|
+
var titleElement = arrowIconSvg.querySelector('title');
|
|
660
|
+
expect(titleElement).toBeInTheDocument();
|
|
661
|
+
expect(titleElement).toHaveTextContent('');
|
|
662
|
+
});
|
|
@@ -180,8 +180,9 @@ var TabPicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
|
|
|
180
180
|
color: isTabFocused || (0, _includes["default"])(classNames).call(classNames, 'is-hovered') ? 'active' : 'neutral.40',
|
|
181
181
|
icon: isOpen ? _ArrowDropUpIcon["default"] : _ArrowDropDownIcon["default"],
|
|
182
182
|
title: {
|
|
183
|
-
name:
|
|
184
|
-
}
|
|
183
|
+
name: ''
|
|
184
|
+
},
|
|
185
|
+
"aria-hidden": "true"
|
|
185
186
|
}))), (0, _react2.jsx)(_.Menu, {
|
|
186
187
|
onAction: setSelectedItem,
|
|
187
188
|
selectionMode: "single",
|
|
@@ -222,8 +222,9 @@ var CustomPopover = function CustomPopover() {
|
|
|
222
222
|
mr: "sm",
|
|
223
223
|
size: "sm",
|
|
224
224
|
title: {
|
|
225
|
-
name:
|
|
226
|
-
}
|
|
225
|
+
name: ''
|
|
226
|
+
},
|
|
227
|
+
"aria-hidden": "true"
|
|
227
228
|
}))), (0, _react2.jsx)(_index.PopoverContainer, (0, _extends2["default"])({}, overlayProps, positionProps, {
|
|
228
229
|
isOpen: state.isOpen,
|
|
229
230
|
hasNoArrow: true,
|
|
@@ -36,8 +36,9 @@ var CustomPopoverMenu = function CustomPopoverMenu() {
|
|
|
36
36
|
transform: 'rotate(180deg)'
|
|
37
37
|
} : null,
|
|
38
38
|
title: {
|
|
39
|
-
name: '
|
|
40
|
-
}
|
|
39
|
+
name: ''
|
|
40
|
+
},
|
|
41
|
+
"aria-hidden": "true"
|
|
41
42
|
})), (0, _react2.jsx)(_index.Menu, null, (0, _react2.jsx)(_index.Item, {
|
|
42
43
|
key: "option1"
|
|
43
44
|
}, "First Option"), (0, _react2.jsx)(_index.Item, {
|
|
@@ -81,7 +81,7 @@ var fieldControlWrapper = exports.fieldControlWrapper = {
|
|
|
81
81
|
'> textarea': {
|
|
82
82
|
borderRadius: _onyxTokens.astroTokens.radius.input,
|
|
83
83
|
border: '1px solid',
|
|
84
|
-
borderColor: 'border.input
|
|
84
|
+
borderColor: 'border.input',
|
|
85
85
|
outline: 'none'
|
|
86
86
|
},
|
|
87
87
|
'&.is-disabled': {
|
|
@@ -332,27 +332,17 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
332
332
|
_context.next = 13;
|
|
333
333
|
return _userEvent["default"].hover(helpHintButton);
|
|
334
334
|
case 13:
|
|
335
|
-
|
|
336
|
-
_context.next = 18;
|
|
337
|
-
break;
|
|
338
|
-
}
|
|
339
|
-
_context.next = 16;
|
|
335
|
+
_context.next = 15;
|
|
340
336
|
return (0, _react2.waitFor)(function () {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
_context.next = 20;
|
|
347
|
-
break;
|
|
348
|
-
case 18:
|
|
349
|
-
_context.next = 20;
|
|
350
|
-
return (0, _react2.waitFor)(function () {
|
|
351
|
-
expect(_react2.screen.queryByRole('presentation')).toHaveAttribute('data-popover-placement', 'left');
|
|
337
|
+
var presentationEls = _react2.screen.queryAllByRole('presentation');
|
|
338
|
+
var popover = (0, _find["default"])(presentationEls).call(presentationEls, function (el) {
|
|
339
|
+
return el.hasAttribute('data-popover-placement');
|
|
340
|
+
});
|
|
341
|
+
expect(popover).toHaveAttribute('data-popover-placement', 'left');
|
|
352
342
|
}, {
|
|
353
343
|
timeout: 100
|
|
354
344
|
});
|
|
355
|
-
case
|
|
345
|
+
case 15:
|
|
356
346
|
case "end":
|
|
357
347
|
return _context.stop();
|
|
358
348
|
}
|
|
@@ -105,8 +105,9 @@ var AccordionGridItemHeader = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
105
105
|
}, isOnyx && {
|
|
106
106
|
size: 'sm'
|
|
107
107
|
}, {
|
|
108
|
+
"aria-hidden": "true",
|
|
108
109
|
title: {
|
|
109
|
-
name:
|
|
110
|
+
name: ''
|
|
110
111
|
}
|
|
111
112
|
})))));
|
|
112
113
|
});
|
|
@@ -90,13 +90,15 @@ var AccordionItem = function AccordionItem(props) {
|
|
|
90
90
|
sx: accordionHoveredState
|
|
91
91
|
}, item.props.label), ___EmotionJSX(Box, {
|
|
92
92
|
as: "span",
|
|
93
|
-
ml: accordionItemMarginLeft
|
|
93
|
+
ml: accordionItemMarginLeft,
|
|
94
|
+
role: "presentation"
|
|
94
95
|
}, ___EmotionJSX(Icon, {
|
|
95
96
|
color: "font.base",
|
|
96
97
|
icon: isOpen ? MenuUp : MenuDown,
|
|
97
98
|
size: "sm",
|
|
99
|
+
"aria-hidden": "true",
|
|
98
100
|
title: {
|
|
99
|
-
name:
|
|
101
|
+
name: ''
|
|
100
102
|
}
|
|
101
103
|
}))), ((_item$props$slots = item.props.slots) === null || _item$props$slots === void 0 ? void 0 : _item$props$slots.postHeading) && ((_item$props$slots2 = item.props.slots) === null || _item$props$slots2 === void 0 ? void 0 : _item$props$slots2.postHeading)), isOpen && ___EmotionJSX(Box, _extends({
|
|
102
104
|
variant: "accordion.body"
|
|
@@ -133,8 +133,8 @@ test('renders detailed button preview mode correctly', function () {
|
|
|
133
133
|
expect(screen.getByText(testLabel)).toBeInTheDocument();
|
|
134
134
|
expect(screen.getByText(testColor1.toLocaleUpperCase())).toBeInTheDocument();
|
|
135
135
|
});
|
|
136
|
-
test('renders MenuUp / MenuDown icon
|
|
137
|
-
var button;
|
|
136
|
+
test('renders MenuUp / MenuDown icon with aria-hidden="true" so screen readers skip it', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
137
|
+
var button, closedIcon, openIcon;
|
|
138
138
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
139
139
|
while (1) switch (_context3.prev = _context3.next) {
|
|
140
140
|
case 0:
|
|
@@ -142,16 +142,20 @@ test('renders MenuUp / MenuDown icon correctly', /*#__PURE__*/_asyncToGenerator(
|
|
|
142
142
|
mode: 'detailed-button-preview',
|
|
143
143
|
value: testColor1
|
|
144
144
|
});
|
|
145
|
-
button = screen.getByRole('button');
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
expect(
|
|
145
|
+
button = screen.getByRole('button'); // Before opening: the closed-state icon (MenuDown) is rendered inside a
|
|
146
|
+
// role="presentation" box and must carry aria-hidden="true".
|
|
147
|
+
closedIcon = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
148
|
+
expect(closedIcon).toBeInTheDocument();
|
|
149
|
+
expect(closedIcon).toHaveAttribute('aria-hidden', 'true');
|
|
150
150
|
_context3.next = 7;
|
|
151
151
|
return userEvent.click(button);
|
|
152
152
|
case 7:
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
// After opening: the open-state icon (MenuUp) replaces MenuDown and must also
|
|
154
|
+
// carry aria-hidden="true".
|
|
155
|
+
openIcon = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
156
|
+
expect(openIcon).toBeInTheDocument();
|
|
157
|
+
expect(openIcon).toHaveAttribute('aria-hidden', 'true');
|
|
158
|
+
case 10:
|
|
155
159
|
case "end":
|
|
156
160
|
return _context3.stop();
|
|
157
161
|
}
|
|
@@ -40,15 +40,18 @@ var ColorFieldPreviewButton = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
40
40
|
sx: {
|
|
41
41
|
ml: 'auto'
|
|
42
42
|
},
|
|
43
|
-
flexGrow: "1"
|
|
43
|
+
flexGrow: "1",
|
|
44
|
+
role: "presentation"
|
|
44
45
|
}, ___EmotionJSX(Icon, _extends({
|
|
45
46
|
ml: "auto",
|
|
46
47
|
title: {
|
|
47
|
-
name:
|
|
48
|
+
name: ''
|
|
48
49
|
},
|
|
49
50
|
icon: isOpen ? MenuUp : MenuDown
|
|
50
51
|
}, isOnyx && {
|
|
51
52
|
size: 'sm'
|
|
53
|
+
}, {
|
|
54
|
+
"aria-hidden": "true"
|
|
52
55
|
})))));
|
|
53
56
|
});
|
|
54
57
|
export default ColorFieldPreviewButton;
|
|
@@ -284,18 +284,24 @@ var TableColumnHeader = function TableColumnHeader(props) {
|
|
|
284
284
|
columnHeaderProps = _useTableColumnHeader.columnHeaderProps;
|
|
285
285
|
var columnProps = column.props;
|
|
286
286
|
var iconSize = isOnyx ? 16 : 24;
|
|
287
|
+
// Sort-direction icons are purely presentational; aria-sort on the <th> conveys
|
|
288
|
+
// sort state to screen readers. Pass aria-hidden="true" to remove the SVG from
|
|
289
|
+
// the accessibility tree, and title={{ name: '' }} to suppress the browser-native
|
|
290
|
+
// hover tooltip that the MDI icon package would otherwise generate.
|
|
287
291
|
var arrowIcon = ((_state$sortDescriptor = state.sortDescriptor) === null || _state$sortDescriptor === void 0 ? void 0 : _state$sortDescriptor.direction) === 'ascending' && column.key === ((_state$sortDescriptor2 = state.sortDescriptor) === null || _state$sortDescriptor2 === void 0 ? void 0 : _state$sortDescriptor2.column) ? ___EmotionJSX(Icon, {
|
|
288
292
|
size: iconSize,
|
|
289
293
|
icon: Ascending,
|
|
294
|
+
"aria-hidden": "true",
|
|
290
295
|
title: {
|
|
291
|
-
name: '
|
|
296
|
+
name: ''
|
|
292
297
|
}
|
|
293
298
|
}) : ___EmotionJSX(Icon, {
|
|
294
299
|
size: iconSize,
|
|
295
300
|
icon: Descending,
|
|
296
301
|
color: "active",
|
|
302
|
+
"aria-hidden": "true",
|
|
297
303
|
title: {
|
|
298
|
-
name: '
|
|
304
|
+
name: ''
|
|
299
305
|
}
|
|
300
306
|
});
|
|
301
307
|
var allProps = [columnHeaderProps];
|
|
@@ -248,10 +248,11 @@ var EnvironmentBreadcrumb = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
248
248
|
}), selectedItem, ___EmotionJSX(Icon, {
|
|
249
249
|
icon: popoverState.isOpen ? MenuUp : MenuDown,
|
|
250
250
|
title: {
|
|
251
|
-
name:
|
|
251
|
+
name: ''
|
|
252
252
|
},
|
|
253
253
|
size: "xs",
|
|
254
|
-
ml: "xs"
|
|
254
|
+
ml: "xs",
|
|
255
|
+
"aria-hidden": "true"
|
|
255
256
|
})), ___EmotionJSX(PopoverContainer, _extends({}, overlayProps, positionProps, mergeProps(overlayProps, positionProps, popoverProps), {
|
|
256
257
|
ref: overlayRef,
|
|
257
258
|
isOpen: popoverState.isOpen,
|
|
@@ -34,6 +34,21 @@ var IconDefault = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
34
34
|
sizeProps = _useTShirtSize.sizeProps;
|
|
35
35
|
var defaultIconColor = theme.defaultIconColor,
|
|
36
36
|
isOnyx = theme.themeState.isOnyx;
|
|
37
|
+
|
|
38
|
+
// `role="img"` below is intentional for non-hidden icons: it exposes the icon
|
|
39
|
+
// to the accessibility tree with a meaningful name derived from `resolvedTitle`.
|
|
40
|
+
//
|
|
41
|
+
// Callers that render a purely presentational icon (e.g. a decorative arrow)
|
|
42
|
+
// must pass BOTH props together:
|
|
43
|
+
// aria-hidden="true" — removes the element from the accessibility tree so
|
|
44
|
+
// screen readers skip it entirely.
|
|
45
|
+
// title={{ name: '' }} — renders an empty SVG <title> element, suppressing
|
|
46
|
+
// the browser-native tooltip that the MDI icon package
|
|
47
|
+
// would otherwise produce from its auto-generated UUID
|
|
48
|
+
// title string.
|
|
49
|
+
// `aria-hidden` alone is sufficient for screen readers, but without the empty
|
|
50
|
+
// title prop the SVG <title> can still surface as a tooltip on hover in some
|
|
51
|
+
// browsers, so both props are needed for a complete presentational treatment.
|
|
37
52
|
var resolvedTitle = title !== null && title !== void 0 ? title : _typeof(IconComponent) === 'object' && 'type' in IconComponent ? {
|
|
38
53
|
name: IconComponent.type.name
|
|
39
54
|
} : '';
|
|
@@ -73,7 +73,7 @@ var LinkSelectField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
73
73
|
variant: "loader.withinInput"
|
|
74
74
|
}), ___EmotionJSX(Box, {
|
|
75
75
|
as: "span",
|
|
76
|
-
|
|
76
|
+
role: "presentation",
|
|
77
77
|
variant: "forms.select.arrow"
|
|
78
78
|
}, ___EmotionJSX(Icon, _extends({
|
|
79
79
|
icon: MenuDown,
|
|
@@ -81,7 +81,8 @@ var LinkSelectField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
81
81
|
name: ''
|
|
82
82
|
},
|
|
83
83
|
color: isOnyx ? 'font.link' : 'active',
|
|
84
|
-
size: linkSelectFieldIcon
|
|
84
|
+
size: linkSelectFieldIcon,
|
|
85
|
+
"aria-hidden": "true"
|
|
85
86
|
}, iconProps, {
|
|
86
87
|
sx: _objectSpread({
|
|
87
88
|
transform: state.isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
@@ -71,8 +71,9 @@ var ListViewExpandableItem = function ListViewExpandableItem(props) {
|
|
|
71
71
|
icon: isExpanded ? MenuUp : MenuDown,
|
|
72
72
|
variant: "listViewItem.expandIcon",
|
|
73
73
|
title: {
|
|
74
|
-
name:
|
|
75
|
-
}
|
|
74
|
+
name: ''
|
|
75
|
+
},
|
|
76
|
+
"aria-hidden": "true"
|
|
76
77
|
}, isOnyx && {
|
|
77
78
|
size: 'sm'
|
|
78
79
|
})))), ___EmotionJSX(Box, expandableItemState.gridCellProps, isExpanded && ___EmotionJSX(ListViewFocusWrapper, {
|
|
@@ -383,14 +383,15 @@ var CondensedMultivaluesField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
383
383
|
sx: {
|
|
384
384
|
border: 'none'
|
|
385
385
|
},
|
|
386
|
-
|
|
387
|
-
name: ''
|
|
388
|
-
}
|
|
386
|
+
"aria-label": isOpen ? 'Close menu' : 'Open menu'
|
|
389
387
|
}, ___EmotionJSX(Icon, _extends({
|
|
390
388
|
icon: isOpen ? MenuUp : MenuDown
|
|
391
389
|
}, isOnyx && {
|
|
392
390
|
size: 'sm'
|
|
393
391
|
}, {
|
|
392
|
+
title: {
|
|
393
|
+
name: ''
|
|
394
|
+
},
|
|
394
395
|
"aria-hidden": "true"
|
|
395
396
|
}))));
|
|
396
397
|
return ___EmotionJSX(MultivaluesContext.Provider, {
|
|
@@ -508,10 +509,10 @@ CondensedMultivaluesField.propTypes = _objectSpread(_objectSpread(_objectSpread(
|
|
|
508
509
|
*/
|
|
509
510
|
onKeyDown: PropTypes.func,
|
|
510
511
|
/**
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
512
|
+
* Handler that is called when a key is released.
|
|
513
|
+
*
|
|
514
|
+
* `(e: KeyboardEvent) => void`
|
|
515
|
+
*/
|
|
515
516
|
onKeyUp: PropTypes.func,
|
|
516
517
|
/**
|
|
517
518
|
* Method that is called when the open state of the menu changes.
|
|
@@ -38,8 +38,8 @@ import { isIterableProp } from '../../utils/devUtils/props/isIterable';
|
|
|
38
38
|
import { ariaAttributesBasePropTypes } from '../../utils/docUtils/ariaAttributes';
|
|
39
39
|
import { inputFieldAttributesBasePropTypes } from '../../utils/docUtils/fieldAttributes';
|
|
40
40
|
import { statusDefaultProp, statusPropTypes } from '../../utils/docUtils/statusProp';
|
|
41
|
-
import BadgeLabelTooltip from './BadgeLabelTooltip';
|
|
42
41
|
import ListBox from '../ListBox';
|
|
42
|
+
import BadgeLabelTooltip from './BadgeLabelTooltip';
|
|
43
43
|
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
44
44
|
var DefaultMultivaluesField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
45
45
|
var _context0, _listBoxRef$current2;
|
|
@@ -606,10 +606,10 @@ DefaultMultivaluesField.propTypes = _objectSpread(_objectSpread(_objectSpread({
|
|
|
606
606
|
*/
|
|
607
607
|
onKeyDown: PropTypes.func,
|
|
608
608
|
/**
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
609
|
+
* Handler that is called when a key is released.
|
|
610
|
+
*
|
|
611
|
+
* `(e: KeyboardEvent) => void`
|
|
612
|
+
*/
|
|
613
613
|
onKeyUp: PropTypes.func,
|
|
614
614
|
/**
|
|
615
615
|
* Method that is called when the open state of the menu changes.
|
|
@@ -2054,4 +2054,28 @@ universalFieldComponentTests({
|
|
|
2054
2054
|
testValue: items[0].name,
|
|
2055
2055
|
testLabel: defaultProps.label,
|
|
2056
2056
|
componentType: 'MultivaluesField'
|
|
2057
|
+
});
|
|
2058
|
+
test('in condensed mode, arrow icon SVG has aria-hidden="true" to be hidden from screen readers', function () {
|
|
2059
|
+
getComponent({
|
|
2060
|
+
mode: 'condensed'
|
|
2061
|
+
});
|
|
2062
|
+
// The presentational arrow icon (MenuDown/MenuUp) in the condensed mode trigger
|
|
2063
|
+
// button receives aria-hidden="true" via props, making it invisible to screen
|
|
2064
|
+
// readers. Scope the query to the trigger button (tabIndex=-1) to avoid
|
|
2065
|
+
// accidentally matching any other aria-hidden SVG added in future.
|
|
2066
|
+
var arrowIconSvg = document.querySelector('button[tabindex="-1"] svg[aria-hidden="true"]');
|
|
2067
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
2068
|
+
expect(arrowIconSvg).toHaveAttribute('aria-hidden', 'true');
|
|
2069
|
+
});
|
|
2070
|
+
test('in condensed mode, arrow icon SVG has an empty title element so no tooltip is shown', function () {
|
|
2071
|
+
getComponent({
|
|
2072
|
+
mode: 'condensed'
|
|
2073
|
+
});
|
|
2074
|
+
// title={{ name: '' }} renders an empty SVG <title> element, suppressing
|
|
2075
|
+
// the browser-native tooltip that would otherwise appear on hover.
|
|
2076
|
+
var arrowIconSvg = document.querySelector('button[tabindex="-1"] svg[aria-hidden="true"]');
|
|
2077
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
2078
|
+
var titleElement = arrowIconSvg.querySelector('title');
|
|
2079
|
+
expect(titleElement).toBeInTheDocument();
|
|
2080
|
+
expect(titleElement).toHaveTextContent('');
|
|
2057
2081
|
});
|
|
@@ -11,6 +11,7 @@ var SUBTITLE = 'subtitle';
|
|
|
11
11
|
var TEXT = 'text';
|
|
12
12
|
var data = [{
|
|
13
13
|
key: 'Dashboard',
|
|
14
|
+
heading: 'Dashboard',
|
|
14
15
|
children: ['Users', 'Group', 'Populations', 'Attributes', 'Roles', 'Dashboard Unique']
|
|
15
16
|
}];
|
|
16
17
|
var NavBarWithItemBody = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
@@ -92,8 +92,9 @@ var NavBarSectionItemHeader = function NavBarSectionItemHeader(_ref2) {
|
|
|
92
92
|
fill: getIconColor()
|
|
93
93
|
},
|
|
94
94
|
title: {
|
|
95
|
-
name:
|
|
96
|
-
}
|
|
95
|
+
name: ''
|
|
96
|
+
},
|
|
97
|
+
"aria-hidden": "true"
|
|
97
98
|
})));
|
|
98
99
|
};
|
|
99
100
|
var NavBarPrimaryItemHeader = function NavBarPrimaryItemHeader(_ref3) {
|
|
@@ -80,9 +80,9 @@ var NavSideBarSectionHeader = function NavSideBarSectionHeader(props) {
|
|
|
80
80
|
variant: variant,
|
|
81
81
|
mr: "0",
|
|
82
82
|
title: {
|
|
83
|
-
name:
|
|
83
|
+
name: ''
|
|
84
84
|
},
|
|
85
|
-
"aria-
|
|
85
|
+
"aria-hidden": "true"
|
|
86
86
|
}))));
|
|
87
87
|
};
|
|
88
88
|
export default NavSideBarSectionHeader;
|
|
@@ -75,14 +75,15 @@ var SelectFieldBase = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
75
75
|
};
|
|
76
76
|
var buttonRendered = !(hasClearButton && state.selectedKey) && ___EmotionJSX(Box, {
|
|
77
77
|
as: "span",
|
|
78
|
-
|
|
78
|
+
role: "presentation",
|
|
79
79
|
variant: "forms.select.arrow"
|
|
80
80
|
}, ___EmotionJSX(Icon, {
|
|
81
81
|
icon: state.isOpen ? MenuUp : MenuDown,
|
|
82
82
|
title: {
|
|
83
83
|
name: ''
|
|
84
84
|
},
|
|
85
|
-
size: isOnyx ? 'sm' : 'md'
|
|
85
|
+
size: isOnyx ? 'sm' : 'md',
|
|
86
|
+
"aria-hidden": "true"
|
|
86
87
|
}));
|
|
87
88
|
var clearButton = hasClearButton && state.selectedKey && ___EmotionJSX(IconButton, _extends({
|
|
88
89
|
tabIndex: 0,
|
|
@@ -634,4 +634,23 @@ test('should have call onClear function', /*#__PURE__*/_asyncToGenerator(/*#__PU
|
|
|
634
634
|
return _context13.stop();
|
|
635
635
|
}
|
|
636
636
|
}, _callee13);
|
|
637
|
-
})));
|
|
637
|
+
})));
|
|
638
|
+
test('arrow icon SVG has aria-hidden="true" to be hidden from screen readers', function () {
|
|
639
|
+
getComponent();
|
|
640
|
+
// The presentational arrow icon (MenuDown/MenuUp) is rendered inside a
|
|
641
|
+
// role="presentation" span. The Icon component renders as an SVG element
|
|
642
|
+
// and receives aria-hidden="true" via props, making it invisible to screen readers.
|
|
643
|
+
var arrowIconSvg = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
644
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
645
|
+
expect(arrowIconSvg).toHaveAttribute('aria-hidden', 'true');
|
|
646
|
+
});
|
|
647
|
+
test('arrow icon SVG has an empty title element so no tooltip is shown', function () {
|
|
648
|
+
getComponent();
|
|
649
|
+
// title={{ name: '' }} renders an empty SVG <title> element, suppressing
|
|
650
|
+
// the browser-native tooltip that would otherwise appear on hover.
|
|
651
|
+
var arrowIconSvg = document.querySelector('[role="presentation"] svg[aria-hidden="true"]');
|
|
652
|
+
expect(arrowIconSvg).toBeInTheDocument();
|
|
653
|
+
var titleElement = arrowIconSvg.querySelector('title');
|
|
654
|
+
expect(titleElement).toBeInTheDocument();
|
|
655
|
+
expect(titleElement).toHaveTextContent('');
|
|
656
|
+
});
|
|
@@ -169,8 +169,9 @@ var TabPicker = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
169
169
|
color: isTabFocused || _includesInstanceProperty(classNames).call(classNames, 'is-hovered') ? 'active' : 'neutral.40',
|
|
170
170
|
icon: isOpen ? ArrowDropUpIcon : ArrowDropDownIcon,
|
|
171
171
|
title: {
|
|
172
|
-
name:
|
|
173
|
-
}
|
|
172
|
+
name: ''
|
|
173
|
+
},
|
|
174
|
+
"aria-hidden": "true"
|
|
174
175
|
}))), ___EmotionJSX(Menu, {
|
|
175
176
|
onAction: setSelectedItem,
|
|
176
177
|
selectionMode: "single",
|
|
@@ -212,8 +212,9 @@ var CustomPopover = function CustomPopover() {
|
|
|
212
212
|
mr: "sm",
|
|
213
213
|
size: "sm",
|
|
214
214
|
title: {
|
|
215
|
-
name:
|
|
216
|
-
}
|
|
215
|
+
name: ''
|
|
216
|
+
},
|
|
217
|
+
"aria-hidden": "true"
|
|
217
218
|
}))), ___EmotionJSX(PopoverContainer, _extends({}, overlayProps, positionProps, {
|
|
218
219
|
isOpen: state.isOpen,
|
|
219
220
|
hasNoArrow: true,
|
|
@@ -24,8 +24,9 @@ var CustomPopoverMenu = function CustomPopoverMenu() {
|
|
|
24
24
|
transform: 'rotate(180deg)'
|
|
25
25
|
} : null,
|
|
26
26
|
title: {
|
|
27
|
-
name: '
|
|
28
|
-
}
|
|
27
|
+
name: ''
|
|
28
|
+
},
|
|
29
|
+
"aria-hidden": "true"
|
|
29
30
|
})), ___EmotionJSX(Menu, null, ___EmotionJSX(Item, {
|
|
30
31
|
key: "option1"
|
|
31
32
|
}, "First Option"), ___EmotionJSX(Item, {
|
|
@@ -322,27 +322,17 @@ export var universalFieldComponentTests = function universalFieldComponentTests(
|
|
|
322
322
|
_context.next = 13;
|
|
323
323
|
return userEvent.hover(helpHintButton);
|
|
324
324
|
case 13:
|
|
325
|
-
|
|
326
|
-
_context.next = 18;
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
_context.next = 16;
|
|
325
|
+
_context.next = 15;
|
|
330
326
|
return waitFor(function () {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
_context.next = 20;
|
|
337
|
-
break;
|
|
338
|
-
case 18:
|
|
339
|
-
_context.next = 20;
|
|
340
|
-
return waitFor(function () {
|
|
341
|
-
expect(screen.queryByRole('presentation')).toHaveAttribute('data-popover-placement', 'left');
|
|
327
|
+
var presentationEls = screen.queryAllByRole('presentation');
|
|
328
|
+
var popover = _findInstanceProperty(presentationEls).call(presentationEls, function (el) {
|
|
329
|
+
return el.hasAttribute('data-popover-placement');
|
|
330
|
+
});
|
|
331
|
+
expect(popover).toHaveAttribute('data-popover-placement', 'left');
|
|
342
332
|
}, {
|
|
343
333
|
timeout: 100
|
|
344
334
|
});
|
|
345
|
-
case
|
|
335
|
+
case 15:
|
|
346
336
|
case "end":
|
|
347
337
|
return _context.stop();
|
|
348
338
|
}
|