@instructure/ui-navigation 10.16.0 → 10.16.1-pr-snapshot-1744893671793
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/CHANGELOG.md +8 -0
- package/es/AppNav/Item/__new-tests__/Item.test.js +26 -17
- package/es/AppNav/Item/index.js +11 -8
- package/es/AppNav/__new-tests__/AppNav.test.js +60 -53
- package/es/AppNav/index.js +32 -24
- package/lib/AppNav/Item/__new-tests__/Item.test.js +34 -25
- package/lib/AppNav/Item/index.js +10 -8
- package/lib/AppNav/__new-tests__/AppNav.test.js +70 -64
- package/lib/AppNav/index.js +31 -24
- package/package.json +25 -25
- package/src/AppNav/Item/__new-tests__/Item.test.tsx +0 -2
- package/src/AppNav/Item/index.tsx +3 -4
- package/src/AppNav/__new-tests__/AppNav.test.tsx +2 -2
- package/src/AppNav/index.tsx +5 -6
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/AppNav/Item/__new-tests__/Item.test.d.ts.map +1 -1
- package/types/AppNav/Item/index.d.ts +2 -4
- package/types/AppNav/Item/index.d.ts.map +1 -1
- package/types/AppNav/index.d.ts +3 -5
- package/types/AppNav/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.16.1-pr-snapshot-1744893671793](https://github.com/instructure/instructure-ui/compare/v10.16.0...v10.16.1-pr-snapshot-1744893671793) (2025-04-17)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @instructure/ui-navigation
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# [10.16.0](https://github.com/instructure/instructure-ui/compare/v10.15.2...v10.16.0) (2025-04-11)
|
|
7
15
|
|
|
8
16
|
|
|
@@ -23,7 +23,6 @@ var _Item, _Item2, _Item3, _ScreenReaderContent;
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import React from 'react';
|
|
27
26
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
28
27
|
import { vi } from 'vitest';
|
|
29
28
|
import userEvent from '@testing-library/user-event';
|
|
@@ -31,14 +30,18 @@ import '@testing-library/jest-dom';
|
|
|
31
30
|
import { runAxeCheck } from '@instructure/ui-axe-check';
|
|
32
31
|
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
|
33
32
|
import { Item } from '../index';
|
|
34
|
-
|
|
33
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
34
|
+
const icon = _jsxs("svg", {
|
|
35
35
|
height: "24",
|
|
36
|
-
width: "24"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
width: "24",
|
|
37
|
+
children: [_jsx("title", {
|
|
38
|
+
children: "Some icon"
|
|
39
|
+
}), _jsx("circle", {
|
|
40
|
+
cx: "50",
|
|
41
|
+
cy: "50",
|
|
42
|
+
r: "40"
|
|
43
|
+
})]
|
|
44
|
+
});
|
|
42
45
|
describe('<AppNav.Item />', () => {
|
|
43
46
|
let consoleWarningMock;
|
|
44
47
|
let consoleErrorMock;
|
|
@@ -52,7 +55,7 @@ describe('<AppNav.Item />', () => {
|
|
|
52
55
|
consoleErrorMock.mockRestore();
|
|
53
56
|
});
|
|
54
57
|
it('should render label text', async () => {
|
|
55
|
-
render(_Item || (_Item =
|
|
58
|
+
render(_Item || (_Item = _jsx(Item, {
|
|
56
59
|
renderLabel: "Some label",
|
|
57
60
|
href: "#"
|
|
58
61
|
})));
|
|
@@ -60,9 +63,11 @@ describe('<AppNav.Item />', () => {
|
|
|
60
63
|
expect(item).toHaveTextContent('Some label');
|
|
61
64
|
});
|
|
62
65
|
it('should render an icon/image/etc.', async () => {
|
|
63
|
-
const _render = render(_Item2 || (_Item2 =
|
|
66
|
+
const _render = render(_Item2 || (_Item2 = _jsx(Item, {
|
|
64
67
|
renderIcon: icon,
|
|
65
|
-
renderLabel:
|
|
68
|
+
renderLabel: _jsx(ScreenReaderContent, {
|
|
69
|
+
children: "Some label"
|
|
70
|
+
}),
|
|
66
71
|
href: "#"
|
|
67
72
|
}))),
|
|
68
73
|
container = _render.container;
|
|
@@ -75,10 +80,12 @@ describe('<AppNav.Item />', () => {
|
|
|
75
80
|
expect(item).toHaveTextContent('Some label');
|
|
76
81
|
});
|
|
77
82
|
it('should render content after the label text to accommodate badges, etc.', async () => {
|
|
78
|
-
render(_Item3 || (_Item3 =
|
|
83
|
+
render(_Item3 || (_Item3 = _jsx(Item, {
|
|
79
84
|
renderLabel: "Some label",
|
|
80
85
|
href: "#",
|
|
81
|
-
renderAfter:
|
|
86
|
+
renderAfter: _jsx("strong", {
|
|
87
|
+
children: "I am rendered after!"
|
|
88
|
+
})
|
|
82
89
|
})));
|
|
83
90
|
const item = screen.getByRole('link');
|
|
84
91
|
const after = screen.getByText('I am rendered after!');
|
|
@@ -89,7 +96,7 @@ describe('<AppNav.Item />', () => {
|
|
|
89
96
|
});
|
|
90
97
|
it('should respond to an onClick event', async () => {
|
|
91
98
|
const onClick = vi.fn();
|
|
92
|
-
render(
|
|
99
|
+
render(_jsx(Item, {
|
|
93
100
|
renderLabel: "Some label",
|
|
94
101
|
onClick: onClick
|
|
95
102
|
}));
|
|
@@ -100,7 +107,7 @@ describe('<AppNav.Item />', () => {
|
|
|
100
107
|
});
|
|
101
108
|
});
|
|
102
109
|
it('should output a console error if icon is used with non-screenreader label text', async () => {
|
|
103
|
-
render(
|
|
110
|
+
render(_jsx(Item, {
|
|
104
111
|
renderIcon: icon,
|
|
105
112
|
renderLabel: "Some label",
|
|
106
113
|
onClick: () => 'clicked'
|
|
@@ -109,9 +116,11 @@ describe('<AppNav.Item />', () => {
|
|
|
109
116
|
expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
|
|
110
117
|
});
|
|
111
118
|
it('should meet a11y standards', async () => {
|
|
112
|
-
const _render2 = render(
|
|
119
|
+
const _render2 = render(_jsx(Item, {
|
|
113
120
|
renderIcon: icon,
|
|
114
|
-
renderLabel: _ScreenReaderContent || (_ScreenReaderContent =
|
|
121
|
+
renderLabel: _ScreenReaderContent || (_ScreenReaderContent = _jsx(ScreenReaderContent, {
|
|
122
|
+
children: "Some label"
|
|
123
|
+
})),
|
|
115
124
|
onClick: () => 'clicked'
|
|
116
125
|
})),
|
|
117
126
|
container = _render2.container;
|
package/es/AppNav/Item/index.js
CHANGED
|
@@ -23,14 +23,13 @@ var _dec, _dec2, _class, _Item;
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
import React, { Component } from 'react';
|
|
26
|
+
import { Component } from 'react';
|
|
28
27
|
import { logError as error } from '@instructure/console';
|
|
29
28
|
import { callRenderProp, getElementType, matchComponentTypes, passthroughProps } from '@instructure/ui-react-utils';
|
|
30
29
|
import { testable } from '@instructure/ui-testable';
|
|
31
30
|
import { View } from '@instructure/ui-view';
|
|
32
31
|
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
|
33
|
-
import { withStyle
|
|
32
|
+
import { withStyle } from '@instructure/emotion';
|
|
34
33
|
import generateStyle from './styles';
|
|
35
34
|
import generateComponentTheme from './theme';
|
|
36
35
|
import { allowedProps, propTypes } from './props';
|
|
@@ -42,6 +41,7 @@ id: AppNav.Item
|
|
|
42
41
|
---
|
|
43
42
|
@module Item
|
|
44
43
|
**/
|
|
44
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
45
45
|
let Item = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = testable(), _dec(_class = _dec2(_class = (_Item = class Item extends Component {
|
|
46
46
|
constructor(...args) {
|
|
47
47
|
super(...args);
|
|
@@ -89,7 +89,8 @@ let Item = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = tes
|
|
|
89
89
|
if (icon) {
|
|
90
90
|
error(labelIsForScreenReaders, '[AppNav] If an icon is used, the label text should be wrapped in <ScreenReaderContent />.');
|
|
91
91
|
}
|
|
92
|
-
return
|
|
92
|
+
return _jsxs(View, {
|
|
93
|
+
...passthroughProps(this.props),
|
|
93
94
|
as: ElementType,
|
|
94
95
|
href: href,
|
|
95
96
|
onClick: this.handleClick,
|
|
@@ -99,10 +100,12 @@ let Item = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = tes
|
|
|
99
100
|
position: "relative",
|
|
100
101
|
borderRadius: "medium",
|
|
101
102
|
cursor: isDisabled ? 'not-allowed' : cursor,
|
|
102
|
-
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.item
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.item,
|
|
104
|
+
children: [icon, labelIsForScreenReaders ? label : _jsx("span", {
|
|
105
|
+
css: (_this$props$styles2 = this.props.styles) === null || _this$props$styles2 === void 0 ? void 0 : _this$props$styles2.label,
|
|
106
|
+
children: label
|
|
107
|
+
}), renderAfter && callRenderProp(renderAfter)]
|
|
108
|
+
});
|
|
106
109
|
}
|
|
107
110
|
}, _Item.displayName = "Item", _Item.componentId = 'AppNav.Item', _Item.allowedProps = allowedProps, _Item.propTypes = propTypes, _Item.defaultProps = {
|
|
108
111
|
children: null,
|
|
@@ -22,7 +22,7 @@ var _AppNav, _AppNav$Item, _AppNav2, _AppNav3, _AppNav$Item2, _AppNav$Item3, _Ap
|
|
|
22
22
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
import { render, screen } from '@testing-library/react';
|
|
27
27
|
import { vi } from 'vitest';
|
|
28
28
|
import '@testing-library/jest-dom';
|
|
@@ -32,6 +32,7 @@ import { generateA11yTests } from '@instructure/ui-scripts/lib/test/generateA11y
|
|
|
32
32
|
import { runAxeCheck } from '@instructure/ui-axe-check';
|
|
33
33
|
import { AppNav } from '../index';
|
|
34
34
|
import AppNavExamples from '../__examples__/AppNav.examples';
|
|
35
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
35
36
|
describe('<AppNav />', () => {
|
|
36
37
|
let consoleErrorMock;
|
|
37
38
|
beforeEach(() => {
|
|
@@ -43,33 +44,35 @@ describe('<AppNav />', () => {
|
|
|
43
44
|
});
|
|
44
45
|
describe('for a11y', () => {
|
|
45
46
|
it('should render a nav element with an aria-label', async () => {
|
|
46
|
-
const _render = render(_AppNav || (_AppNav =
|
|
47
|
+
const _render = render(_AppNav || (_AppNav = _jsxs(AppNav, {
|
|
47
48
|
screenReaderLabel: "Screen reader label",
|
|
48
|
-
visibleItemsCount: 2
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
visibleItemsCount: 2,
|
|
50
|
+
children: [_jsx(AppNav.Item, {
|
|
51
|
+
renderLabel: "Some label",
|
|
52
|
+
href: "http://instructure.design"
|
|
53
|
+
}), _jsx(AppNav.Item, {
|
|
54
|
+
renderLabel: "Some other label",
|
|
55
|
+
href: "http://instructure.design"
|
|
56
|
+
})]
|
|
57
|
+
}))),
|
|
56
58
|
container = _render.container;
|
|
57
|
-
const appNavList = container.querySelector('ul[class
|
|
59
|
+
const appNavList = container.querySelector('ul[class*="-appNav__list"]');
|
|
58
60
|
expect(appNavList).toBeInTheDocument();
|
|
59
61
|
expect(appNavList.tagName).toBe('UL');
|
|
60
62
|
expect(appNavList).toHaveAttribute('aria-label', 'Screen reader label');
|
|
61
63
|
});
|
|
62
64
|
it('should render a semantic list of items', async () => {
|
|
63
|
-
render(
|
|
65
|
+
render(_jsxs(AppNav, {
|
|
64
66
|
screenReaderLabel: "App navigation",
|
|
65
|
-
visibleItemsCount: 2
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
visibleItemsCount: 2,
|
|
68
|
+
children: [_AppNav$Item || (_AppNav$Item = _jsx(AppNav.Item, {
|
|
69
|
+
renderLabel: "Some first label",
|
|
70
|
+
href: "http://instructure.design"
|
|
71
|
+
})), _jsx(AppNav.Item, {
|
|
72
|
+
renderLabel: "Some second label",
|
|
73
|
+
onClick: () => 'clicked'
|
|
74
|
+
})]
|
|
75
|
+
}));
|
|
73
76
|
const list = screen.getAllByRole('list');
|
|
74
77
|
const items = screen.getAllByRole('listitem');
|
|
75
78
|
const link = screen.getAllByRole('link');
|
|
@@ -80,13 +83,14 @@ describe('<AppNav />', () => {
|
|
|
80
83
|
expect(button.length).toBe(1);
|
|
81
84
|
});
|
|
82
85
|
it('should render with a single item', async () => {
|
|
83
|
-
render(_AppNav2 || (_AppNav2 =
|
|
86
|
+
render(_AppNav2 || (_AppNav2 = _jsx(AppNav, {
|
|
84
87
|
screenReaderLabel: "App navigation",
|
|
85
|
-
visibleItemsCount: 1
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
visibleItemsCount: 1,
|
|
89
|
+
children: _jsx(AppNav.Item, {
|
|
90
|
+
renderLabel: "Some label",
|
|
91
|
+
href: "http://instructure.design"
|
|
92
|
+
})
|
|
93
|
+
})));
|
|
90
94
|
const list = screen.getAllByRole('list');
|
|
91
95
|
const items = screen.getAllByRole('listitem');
|
|
92
96
|
const link = screen.getAllByRole('link');
|
|
@@ -97,44 +101,47 @@ describe('<AppNav />', () => {
|
|
|
97
101
|
});
|
|
98
102
|
describe('with rendered content', () => {
|
|
99
103
|
it('should render content after the navigation', async () => {
|
|
100
|
-
render(_AppNav3 || (_AppNav3 =
|
|
104
|
+
render(_AppNav3 || (_AppNav3 = _jsxs(AppNav, {
|
|
101
105
|
screenReaderLabel: "App navigation",
|
|
102
|
-
renderAfterItems:
|
|
103
|
-
type: "button"
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
renderAfterItems: _jsx("button", {
|
|
107
|
+
type: "button",
|
|
108
|
+
children: "I am rendered after!"
|
|
109
|
+
}),
|
|
110
|
+
visibleItemsCount: 2,
|
|
111
|
+
children: [_jsx(AppNav.Item, {
|
|
112
|
+
renderLabel: "Some label",
|
|
113
|
+
href: "http://instructure.design"
|
|
114
|
+
}), _jsx(AppNav.Item, {
|
|
115
|
+
renderLabel: "Some other label",
|
|
116
|
+
href: "http://instructure.design"
|
|
117
|
+
})]
|
|
118
|
+
})));
|
|
113
119
|
const button = screen.getByRole('button');
|
|
114
120
|
expect(button).toHaveTextContent('I am rendered after!');
|
|
115
121
|
});
|
|
116
122
|
});
|
|
117
123
|
describe('with item truncation', () => {
|
|
118
124
|
it('should pass a custom label to the menu trigger', async () => {
|
|
119
|
-
render(
|
|
125
|
+
render(_jsxs(AppNav, {
|
|
120
126
|
screenReaderLabel: "App navigation",
|
|
121
127
|
visibleItemsCount: 2,
|
|
122
128
|
renderTruncateLabel: function () {
|
|
123
129
|
return 'I am sooo custom!';
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
130
|
+
},
|
|
131
|
+
children: [_AppNav$Item2 || (_AppNav$Item2 = _jsx(AppNav.Item, {
|
|
132
|
+
renderLabel: "Label",
|
|
133
|
+
href: "http://instructure.design"
|
|
134
|
+
})), _AppNav$Item3 || (_AppNav$Item3 = _jsx(AppNav.Item, {
|
|
135
|
+
renderLabel: "Label",
|
|
136
|
+
href: "http://instructure.design"
|
|
137
|
+
})), _AppNav$Item4 || (_AppNav$Item4 = _jsx(AppNav.Item, {
|
|
138
|
+
renderLabel: "Label",
|
|
139
|
+
href: "http://instructure.design"
|
|
140
|
+
})), _AppNav$Item5 || (_AppNav$Item5 = _jsx(AppNav.Item, {
|
|
141
|
+
renderLabel: "Label",
|
|
142
|
+
href: "http://instructure.design"
|
|
143
|
+
}))]
|
|
144
|
+
}));
|
|
138
145
|
const items = screen.getAllByRole('listitem');
|
|
139
146
|
expect(items.length).toBe(3);
|
|
140
147
|
expect(items[2]).toHaveTextContent('I am sooo custom!');
|
package/es/AppNav/index.js
CHANGED
|
@@ -23,9 +23,8 @@ var _dec, _dec2, _class, _AppNav;
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
import
|
|
28
|
-
import { withStyle, jsx } from '@instructure/emotion';
|
|
26
|
+
import { Component } from 'react';
|
|
27
|
+
import { withStyle } from '@instructure/emotion';
|
|
29
28
|
import { callRenderProp, omitProps } from '@instructure/ui-react-utils';
|
|
30
29
|
import { testable } from '@instructure/ui-testable';
|
|
31
30
|
import { View } from '@instructure/ui-view';
|
|
@@ -41,6 +40,7 @@ import { TruncateList } from '@instructure/ui-truncate-list';
|
|
|
41
40
|
category: components
|
|
42
41
|
---
|
|
43
42
|
**/
|
|
43
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
44
44
|
let AppNav = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = testable(), _dec(_class = _dec2(_class = (_AppNav = class AppNav extends Component {
|
|
45
45
|
constructor(...args) {
|
|
46
46
|
super(...args);
|
|
@@ -65,17 +65,18 @@ let AppNav = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = t
|
|
|
65
65
|
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
|
|
66
66
|
}
|
|
67
67
|
renderMenu(items) {
|
|
68
|
-
return
|
|
69
|
-
trigger:
|
|
68
|
+
return _jsx(Menu, {
|
|
69
|
+
trigger: _jsx(AppNav.Item, {
|
|
70
70
|
renderLabel: callRenderProp(this.props.renderTruncateLabel)
|
|
71
|
+
}),
|
|
72
|
+
children: items.map((item, index) => {
|
|
73
|
+
return _jsx(Menu.Item, {
|
|
74
|
+
href: item.props.href ? item.props.href : void 0,
|
|
75
|
+
onClick: item.props.onClick && !item.props.href ? item.props.onClick : void 0,
|
|
76
|
+
children: callRenderProp(item.props.renderLabel)
|
|
77
|
+
}, index);
|
|
71
78
|
})
|
|
72
|
-
}
|
|
73
|
-
return jsx(Menu.Item, {
|
|
74
|
-
href: item.props.href ? item.props.href : void 0,
|
|
75
|
-
onClick: item.props.onClick && !item.props.href ? item.props.onClick : void 0,
|
|
76
|
-
key: index
|
|
77
|
-
}, callRenderProp(item.props.renderLabel));
|
|
78
|
-
}));
|
|
79
|
+
});
|
|
79
80
|
}
|
|
80
81
|
render() {
|
|
81
82
|
const _this$props3 = this.props,
|
|
@@ -88,22 +89,29 @@ let AppNav = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = t
|
|
|
88
89
|
const renderBeforeItems = callRenderProp(this.props.renderBeforeItems);
|
|
89
90
|
const renderAfterItems = callRenderProp(this.props.renderAfterItems);
|
|
90
91
|
const hasRenderedContent = renderBeforeItems || renderAfterItems;
|
|
91
|
-
return
|
|
92
|
+
return _jsxs(View, {
|
|
93
|
+
...passthroughProps,
|
|
92
94
|
as: "nav",
|
|
93
95
|
css: [styles === null || styles === void 0 ? void 0 : styles.appNav, hasRenderedContent ? styles === null || styles === void 0 ? void 0 : styles.alignCenter : ''],
|
|
94
96
|
margin: margin,
|
|
95
97
|
display: hasRenderedContent ? 'flex' : 'block',
|
|
96
|
-
elementRef: this.handleRef
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
elementRef: this.handleRef,
|
|
99
|
+
children: [renderBeforeItems && _jsx("span", {
|
|
100
|
+
children: renderBeforeItems
|
|
101
|
+
}), _jsx(TruncateList, {
|
|
102
|
+
visibleItemsCount: visibleItemsCount,
|
|
103
|
+
debounce: debounce,
|
|
104
|
+
onUpdate: this.props.onUpdate,
|
|
105
|
+
renderHiddenItemMenu: hiddenChildren => this.renderMenu(hiddenChildren),
|
|
106
|
+
itemSpacing: styles === null || styles === void 0 ? void 0 : styles.horizontalMargin,
|
|
107
|
+
fixMenuTriggerWidth: styles === null || styles === void 0 ? void 0 : styles.menuTriggerWidth,
|
|
108
|
+
css: styles === null || styles === void 0 ? void 0 : styles.list,
|
|
109
|
+
"aria-label": callRenderProp(screenReaderLabel),
|
|
110
|
+
children: this.props.children
|
|
111
|
+
}), renderAfterItems && _jsx("span", {
|
|
112
|
+
children: renderAfterItems
|
|
113
|
+
})]
|
|
114
|
+
});
|
|
107
115
|
}
|
|
108
116
|
}, _AppNav.displayName = "AppNav", _AppNav.componentId = 'AppNav', _AppNav.allowedProps = allowedProps, _AppNav.propTypes = propTypes, _AppNav.defaultProps = {
|
|
109
117
|
children: null,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
var _react =
|
|
5
|
-
var _react2 = require("@testing-library/react");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
6
5
|
var _vitest = require("vitest");
|
|
7
6
|
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
8
7
|
require("@testing-library/jest-dom");
|
|
9
8
|
var _runAxeCheck = require("@instructure/ui-axe-check/lib/runAxeCheck.js");
|
|
10
9
|
var _ScreenReaderContent2 = require("@instructure/ui-a11y-content/lib/ScreenReaderContent");
|
|
11
10
|
var _index = require("../index");
|
|
11
|
+
var _jsxRuntime = require("@emotion/react/jsx-runtime");
|
|
12
12
|
var _Item, _Item2, _Item3, _ScreenReaderContent;
|
|
13
13
|
/*
|
|
14
14
|
* The MIT License (MIT)
|
|
@@ -33,14 +33,17 @@ var _Item, _Item2, _Item3, _ScreenReaderContent;
|
|
|
33
33
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
34
34
|
* SOFTWARE.
|
|
35
35
|
*/
|
|
36
|
-
const icon =
|
|
36
|
+
const icon = (0, _jsxRuntime.jsxs)("svg", {
|
|
37
37
|
height: "24",
|
|
38
|
-
width: "24"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
width: "24",
|
|
39
|
+
children: [(0, _jsxRuntime.jsx)("title", {
|
|
40
|
+
children: "Some icon"
|
|
41
|
+
}), (0, _jsxRuntime.jsx)("circle", {
|
|
42
|
+
cx: "50",
|
|
43
|
+
cy: "50",
|
|
44
|
+
r: "40"
|
|
45
|
+
})]
|
|
46
|
+
});
|
|
44
47
|
describe('<AppNav.Item />', () => {
|
|
45
48
|
let consoleWarningMock;
|
|
46
49
|
let consoleErrorMock;
|
|
@@ -54,36 +57,40 @@ describe('<AppNav.Item />', () => {
|
|
|
54
57
|
consoleErrorMock.mockRestore();
|
|
55
58
|
});
|
|
56
59
|
it('should render label text', async () => {
|
|
57
|
-
(0,
|
|
60
|
+
(0, _react.render)(_Item || (_Item = (0, _jsxRuntime.jsx)(_index.Item, {
|
|
58
61
|
renderLabel: "Some label",
|
|
59
62
|
href: "#"
|
|
60
63
|
})));
|
|
61
|
-
const item =
|
|
64
|
+
const item = _react.screen.getByRole('link');
|
|
62
65
|
expect(item).toHaveTextContent('Some label');
|
|
63
66
|
});
|
|
64
67
|
it('should render an icon/image/etc.', async () => {
|
|
65
|
-
const _render = (0,
|
|
68
|
+
const _render = (0, _react.render)(_Item2 || (_Item2 = (0, _jsxRuntime.jsx)(_index.Item, {
|
|
66
69
|
renderIcon: icon,
|
|
67
|
-
renderLabel:
|
|
70
|
+
renderLabel: (0, _jsxRuntime.jsx)(_ScreenReaderContent2.ScreenReaderContent, {
|
|
71
|
+
children: "Some label"
|
|
72
|
+
}),
|
|
68
73
|
href: "#"
|
|
69
74
|
}))),
|
|
70
75
|
container = _render.container;
|
|
71
|
-
const iconTitle =
|
|
76
|
+
const iconTitle = _react.screen.getByTitle('Some icon');
|
|
72
77
|
const iconSvg = container.querySelector('svg');
|
|
73
|
-
const item =
|
|
78
|
+
const item = _react.screen.getByRole('link');
|
|
74
79
|
expect(iconTitle).toBeInTheDocument();
|
|
75
80
|
expect(iconSvg).toBeInTheDocument();
|
|
76
81
|
expect(iconSvg).toHaveTextContent('Some icon');
|
|
77
82
|
expect(item).toHaveTextContent('Some label');
|
|
78
83
|
});
|
|
79
84
|
it('should render content after the label text to accommodate badges, etc.', async () => {
|
|
80
|
-
(0,
|
|
85
|
+
(0, _react.render)(_Item3 || (_Item3 = (0, _jsxRuntime.jsx)(_index.Item, {
|
|
81
86
|
renderLabel: "Some label",
|
|
82
87
|
href: "#",
|
|
83
|
-
renderAfter:
|
|
88
|
+
renderAfter: (0, _jsxRuntime.jsx)("strong", {
|
|
89
|
+
children: "I am rendered after!"
|
|
90
|
+
})
|
|
84
91
|
})));
|
|
85
|
-
const item =
|
|
86
|
-
const after =
|
|
92
|
+
const item = _react.screen.getByRole('link');
|
|
93
|
+
const after = _react.screen.getByText('I am rendered after!');
|
|
87
94
|
expect(item).toBeInTheDocument();
|
|
88
95
|
expect(item).toHaveTextContent('Some label');
|
|
89
96
|
expect(after).toBeInTheDocument();
|
|
@@ -91,18 +98,18 @@ describe('<AppNav.Item />', () => {
|
|
|
91
98
|
});
|
|
92
99
|
it('should respond to an onClick event', async () => {
|
|
93
100
|
const onClick = _vitest.vi.fn();
|
|
94
|
-
(0,
|
|
101
|
+
(0, _react.render)((0, _jsxRuntime.jsx)(_index.Item, {
|
|
95
102
|
renderLabel: "Some label",
|
|
96
103
|
onClick: onClick
|
|
97
104
|
}));
|
|
98
|
-
const button =
|
|
105
|
+
const button = _react.screen.getByRole('button');
|
|
99
106
|
await _userEvent.default.click(button);
|
|
100
|
-
await (0,
|
|
107
|
+
await (0, _react.waitFor)(() => {
|
|
101
108
|
expect(onClick).toHaveBeenCalledTimes(1);
|
|
102
109
|
});
|
|
103
110
|
});
|
|
104
111
|
it('should output a console error if icon is used with non-screenreader label text', async () => {
|
|
105
|
-
(0,
|
|
112
|
+
(0, _react.render)((0, _jsxRuntime.jsx)(_index.Item, {
|
|
106
113
|
renderIcon: icon,
|
|
107
114
|
renderLabel: "Some label",
|
|
108
115
|
onClick: () => 'clicked'
|
|
@@ -111,9 +118,11 @@ describe('<AppNav.Item />', () => {
|
|
|
111
118
|
expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
|
|
112
119
|
});
|
|
113
120
|
it('should meet a11y standards', async () => {
|
|
114
|
-
const _render2 = (0,
|
|
121
|
+
const _render2 = (0, _react.render)((0, _jsxRuntime.jsx)(_index.Item, {
|
|
115
122
|
renderIcon: icon,
|
|
116
|
-
renderLabel: _ScreenReaderContent || (_ScreenReaderContent =
|
|
123
|
+
renderLabel: _ScreenReaderContent || (_ScreenReaderContent = (0, _jsxRuntime.jsx)(_ScreenReaderContent2.ScreenReaderContent, {
|
|
124
|
+
children: "Some label"
|
|
125
|
+
})),
|
|
117
126
|
onClick: () => 'clicked'
|
|
118
127
|
})),
|
|
119
128
|
container = _render2.container;
|
package/lib/AppNav/Item/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.default = exports.Item = void 0;
|
|
9
|
-
var _react =
|
|
8
|
+
var _react = require("react");
|
|
10
9
|
var _console = require("@instructure/console");
|
|
11
10
|
var _callRenderProp = require("@instructure/ui-react-utils/lib/callRenderProp.js");
|
|
12
11
|
var _getElementType = require("@instructure/ui-react-utils/lib/getElementType.js");
|
|
@@ -19,6 +18,7 @@ var _emotion = require("@instructure/emotion");
|
|
|
19
18
|
var _styles = _interopRequireDefault(require("./styles"));
|
|
20
19
|
var _theme = _interopRequireDefault(require("./theme"));
|
|
21
20
|
var _props = require("./props");
|
|
21
|
+
var _jsxRuntime = require("@emotion/react/jsx-runtime");
|
|
22
22
|
var _dec, _dec2, _class, _Item;
|
|
23
23
|
/*
|
|
24
24
|
* The MIT License (MIT)
|
|
@@ -43,7 +43,6 @@ var _dec, _dec2, _class, _Item;
|
|
|
43
43
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
44
44
|
* SOFTWARE.
|
|
45
45
|
*/
|
|
46
|
-
/** @jsx jsx */
|
|
47
46
|
/**
|
|
48
47
|
---
|
|
49
48
|
parent: AppNav
|
|
@@ -98,7 +97,8 @@ let Item = exports.Item = (_dec = (0, _emotion.withStyle)(_styles.default, _them
|
|
|
98
97
|
if (icon) {
|
|
99
98
|
(0, _console.logError)(labelIsForScreenReaders, '[AppNav] If an icon is used, the label text should be wrapped in <ScreenReaderContent />.');
|
|
100
99
|
}
|
|
101
|
-
return (0,
|
|
100
|
+
return (0, _jsxRuntime.jsxs)(_View.View, {
|
|
101
|
+
...(0, _passthroughProps.passthroughProps)(this.props),
|
|
102
102
|
as: ElementType,
|
|
103
103
|
href: href,
|
|
104
104
|
onClick: this.handleClick,
|
|
@@ -108,10 +108,12 @@ let Item = exports.Item = (_dec = (0, _emotion.withStyle)(_styles.default, _them
|
|
|
108
108
|
position: "relative",
|
|
109
109
|
borderRadius: "medium",
|
|
110
110
|
cursor: isDisabled ? 'not-allowed' : cursor,
|
|
111
|
-
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.item
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.item,
|
|
112
|
+
children: [icon, labelIsForScreenReaders ? label : (0, _jsxRuntime.jsx)("span", {
|
|
113
|
+
css: (_this$props$styles2 = this.props.styles) === null || _this$props$styles2 === void 0 ? void 0 : _this$props$styles2.label,
|
|
114
|
+
children: label
|
|
115
|
+
}), renderAfter && (0, _callRenderProp.callRenderProp)(renderAfter)]
|
|
116
|
+
});
|
|
115
117
|
}
|
|
116
118
|
}, _Item.displayName = "Item", _Item.componentId = 'AppNav.Item', _Item.allowedProps = _props.allowedProps, _Item.propTypes = _props.propTypes, _Item.defaultProps = {
|
|
117
119
|
children: null,
|