@instructure/ui-tabs 10.14.0 → 10.14.1-snapshot-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/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.14.1-snapshot-0](https://github.com/instructure/instructure-ui/compare/v10.14.0...v10.14.1-snapshot-0) (2025-03-17)
7
+
8
+ **Note:** Version bump only for package @instructure/ui-tabs
9
+
10
+
11
+
12
+
13
+
6
14
  # [10.14.0](https://github.com/instructure/instructure-ui/compare/v10.13.0...v10.14.0) (2025-03-17)
7
15
 
8
16
  **Note:** Version bump only for package @instructure/ui-tabs
@@ -1,3 +1,4 @@
1
+ var _Panel, _Panel2;
1
2
  /*
2
3
  * The MIT License (MIT)
3
4
  *
@@ -21,27 +22,27 @@
21
22
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
23
  * SOFTWARE.
23
24
  */
24
- import { locator } from '@instructure/ui-test-locator';
25
- import { Tabs } from './index';
26
- const TabLocator = locator('[role="tab"]');
27
- const PanelLocator = locator('[role="tabpanel"]');
28
- const SelectedTabLocator = locator('[role="tab"][aria-selected="true"]');
29
25
 
30
- // @ts-expect-error ts-migrate(2339) FIXME: Property 'selector' does not exist on type 'typeof... Remove this comment to see the full error message
31
- export const TabsLocator = locator(Tabs.selector, {
32
- findTab: (...args) => {
33
- return TabLocator.find(...args);
34
- },
35
- findAllTabs: (...args) => {
36
- return TabLocator.findAll(...args);
37
- },
38
- findSelectedTab: (...args) => {
39
- return SelectedTabLocator.find(...args);
40
- },
41
- findTabPanel: (...args) => {
42
- return PanelLocator.find(...args);
43
- },
44
- findAllTabPanels: (...args) => {
45
- return PanelLocator.findAll(...args);
46
- }
26
+ import React from 'react';
27
+ import { render, screen } from '@testing-library/react';
28
+ import '@testing-library/jest-dom';
29
+ import { Panel } from '../index';
30
+ describe('<Tabs.Panel />', () => {
31
+ it('should render children', async () => {
32
+ render(_Panel || (_Panel = /*#__PURE__*/React.createElement(Panel, {
33
+ isSelected: true,
34
+ renderTitle: "Panel Title"
35
+ }, "Panel contents")));
36
+ const children = screen.getByText('Panel contents');
37
+ expect(children).toBeInTheDocument();
38
+ });
39
+ it('should have appropriate role attribute', async () => {
40
+ const _render = render(_Panel2 || (_Panel2 = /*#__PURE__*/React.createElement(Panel, {
41
+ isSelected: true,
42
+ renderTitle: "Panel Title"
43
+ }, "Panel contents"))),
44
+ container = _render.container;
45
+ const tabPanel = container.querySelector('[class$="-panel"]');
46
+ expect(tabPanel).toHaveAttribute('role', 'tabpanel');
47
+ });
47
48
  });
@@ -0,0 +1,175 @@
1
+ var _Tab, _Tab2, _Tab3, _Tab4, _Tab5, _Tab6, _Tab7, _Tab8;
2
+ /*
3
+ * The MIT License (MIT)
4
+ *
5
+ * Copyright (c) 2015 - present Instructure, Inc.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in all
15
+ * copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
24
+ */
25
+
26
+ import React from 'react';
27
+ import { render, screen, waitFor } from '@testing-library/react';
28
+ import { vi } from 'vitest';
29
+ import userEvent from '@testing-library/user-event';
30
+ import '@testing-library/jest-dom';
31
+ import { Tab } from '../index';
32
+ describe('<Tabs.Tab />', () => {
33
+ it('should render children', async () => {
34
+ render(_Tab || (_Tab = /*#__PURE__*/React.createElement(Tab, {
35
+ id: "foo",
36
+ index: 0,
37
+ controls: "foo-panel"
38
+ }, "Tab Label")));
39
+ const children = screen.getByText('Tab Label');
40
+ expect(children).toBeInTheDocument();
41
+ });
42
+ it('should have appropriate role attribute', async () => {
43
+ render(_Tab2 || (_Tab2 = /*#__PURE__*/React.createElement(Tab, {
44
+ id: "foo",
45
+ index: 0,
46
+ controls: "foo-panel"
47
+ }, "Tab Label")));
48
+ const tab = screen.getByRole('tab');
49
+ expect(tab).toBeInTheDocument();
50
+ });
51
+ it('should have appropriate aria attributes', async () => {
52
+ render(_Tab3 || (_Tab3 = /*#__PURE__*/React.createElement(Tab, {
53
+ id: "foo",
54
+ index: 0,
55
+ controls: "foo-panel"
56
+ }, "Tab Label")));
57
+ const tab = screen.getByRole('tab');
58
+ expect(tab).not.toHaveAttribute('aria-selected');
59
+ expect(tab).not.toHaveAttribute('aria-disabled');
60
+ });
61
+ it('should set the aria-selected attribute', async () => {
62
+ render(_Tab4 || (_Tab4 = /*#__PURE__*/React.createElement(Tab, {
63
+ id: "foo",
64
+ index: 0,
65
+ controls: "foo-panel",
66
+ isSelected: true
67
+ }, "Tab Label")));
68
+ const tab = screen.getByRole('tab');
69
+ expect(tab).toHaveAttribute('aria-selected', 'true');
70
+ });
71
+ it('should set the aria-disabled attribute', async () => {
72
+ render(_Tab5 || (_Tab5 = /*#__PURE__*/React.createElement(Tab, {
73
+ id: "foo",
74
+ index: 0,
75
+ controls: "foo-panel",
76
+ isDisabled: true
77
+ }, "Tab Label")));
78
+ const tab = screen.getByRole('tab');
79
+ expect(tab).toHaveAttribute('aria-disabled', 'true');
80
+ });
81
+ it('should set the tabindex to 0 when selected', async () => {
82
+ render(_Tab6 || (_Tab6 = /*#__PURE__*/React.createElement(Tab, {
83
+ id: "foo",
84
+ index: 0,
85
+ controls: "foo-panel",
86
+ isSelected: true
87
+ }, "Tab Label")));
88
+ const tab = screen.getByRole('tab');
89
+ expect(tab).toHaveAttribute('tabindex', '0');
90
+ });
91
+ it('should not set the tabindex when not selected', async () => {
92
+ render(_Tab7 || (_Tab7 = /*#__PURE__*/React.createElement(Tab, {
93
+ id: "foo",
94
+ index: 0,
95
+ controls: "foo-panel"
96
+ }, "Tab Label")));
97
+ const tab = screen.getByRole('tab');
98
+ expect(tab).not.toHaveAttribute('tabindex');
99
+ });
100
+ it('should remove the tabindex attribute when disabled', async () => {
101
+ render(_Tab8 || (_Tab8 = /*#__PURE__*/React.createElement(Tab, {
102
+ id: "foo",
103
+ index: 0,
104
+ controls: "foo-panel",
105
+ isDisabled: true
106
+ }, "Tab Label")));
107
+ const tab = screen.getByRole('tab');
108
+ expect(tab).not.toHaveAttribute('tabindex');
109
+ });
110
+ it('should call onClick when clicked', async () => {
111
+ const onClick = vi.fn();
112
+ const index = 2;
113
+ render(/*#__PURE__*/React.createElement(Tab, {
114
+ id: "foo",
115
+ index: index,
116
+ controls: "foo-panel",
117
+ onClick: onClick
118
+ }, "Tab Label"));
119
+ const tab = screen.getByRole('tab');
120
+ await userEvent.click(tab);
121
+ await waitFor(() => {
122
+ expect(onClick).toHaveBeenCalled();
123
+ const args = onClick.mock.calls[0][1];
124
+ expect(args).toHaveProperty('index', index);
125
+ });
126
+ });
127
+ it('should NOT call onClick when clicked and tab is disabled', async () => {
128
+ const onClick = vi.fn();
129
+ render(/*#__PURE__*/React.createElement(Tab, {
130
+ id: "foo",
131
+ index: 0,
132
+ controls: "foo-panel",
133
+ onClick: onClick,
134
+ isDisabled: true
135
+ }, "Tab Label"));
136
+ const tab = screen.getByRole('tab');
137
+ await userEvent.click(tab);
138
+ await waitFor(() => {
139
+ expect(onClick).not.toHaveBeenCalled();
140
+ });
141
+ });
142
+ it('should call onKeyDown when keys are pressed and tab is selected', async () => {
143
+ const onKeyDown = vi.fn();
144
+ const index = 2;
145
+ render(/*#__PURE__*/React.createElement(Tab, {
146
+ id: "foo",
147
+ isSelected: true,
148
+ index: index,
149
+ controls: "foo-panel",
150
+ onKeyDown: onKeyDown
151
+ }, "Tab Label"));
152
+ const tab = screen.getByRole('tab');
153
+ await userEvent.type(tab, '{enter}');
154
+ await waitFor(() => {
155
+ expect(onKeyDown).toHaveBeenCalled();
156
+ const args = onKeyDown.mock.calls[0][1];
157
+ expect(args).toHaveProperty('index', index);
158
+ });
159
+ });
160
+ it('should NOT call onKeyDown when keys are pressed and tab is disabled', async () => {
161
+ const onKeyDown = vi.fn();
162
+ render(/*#__PURE__*/React.createElement(Tab, {
163
+ id: "foo",
164
+ index: 0,
165
+ controls: "foo-panel",
166
+ onKeyDown: onKeyDown,
167
+ isDisabled: true
168
+ }, "Tab Label"));
169
+ const tab = screen.getByRole('tab');
170
+ await userEvent.type(tab, '{enter}');
171
+ await waitFor(() => {
172
+ expect(onKeyDown).not.toHaveBeenCalled();
173
+ });
174
+ });
175
+ });
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- var _p, _Tabs, _Tabs2, _Tabs3;
2
+ var _p, _Tabs, _Tabs2, _Tabs3, _Tabs4, _Tabs5, _Tabs6, _Tabs9, _Tabs$Panel, _Tabs$Panel2, _Tabs$Panel3, _Tabs10, _Tabs$Panel4, _Tabs$Panel5, _Tabs$Panel6, _Tabs11, _Tabs12, _Tabs13, _Tabs14, _Tabs15;
3
3
  /*
4
4
  * The MIT License (MIT)
5
5
  *
@@ -25,10 +25,12 @@ var _p, _Tabs, _Tabs2, _Tabs3;
25
25
  */
26
26
 
27
27
  import React from 'react';
28
- import { Tabs } from '../index';
29
- import { fireEvent, render, screen } from '@testing-library/react';
28
+ import { render, screen, waitFor } from '@testing-library/react';
30
29
  import { vi } from 'vitest';
30
+ import userEvent from '@testing-library/user-event';
31
31
  import '@testing-library/jest-dom';
32
+ import { runAxeCheck } from '@instructure/ui-axe-check';
33
+ import { Tabs } from '../index';
32
34
  const TabExample = props => {
33
35
  const _React$useState = React.useState(0),
34
36
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -59,13 +61,20 @@ const TabExample = props => {
59
61
  }));
60
62
  };
61
63
  describe('<Tabs />', () => {
64
+ var _Tabs7, _Tabs8;
65
+ const tab1Content = 'Tab 1 content';
66
+ const tab2Content = 'Tab 2 content';
67
+ const tab3Content = 'Tab 3 content';
62
68
  let consoleErrorMock;
69
+ let consoleWarningMock;
63
70
  beforeEach(() => {
64
71
  // Mocking console to prevent test output pollution and expect for messages
65
72
  consoleErrorMock = vi.spyOn(console, 'error').mockImplementation(() => {});
73
+ consoleWarningMock = vi.spyOn(console, 'warn').mockImplementation(() => {});
66
74
  });
67
75
  afterEach(() => {
68
76
  consoleErrorMock.mockRestore();
77
+ consoleWarningMock.mockRestore();
69
78
  });
70
79
  it('should render the correct number of panels', () => {
71
80
  const _render = render(_Tabs || (_Tabs = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
@@ -77,10 +86,40 @@ describe('<Tabs />', () => {
77
86
  isDisabled: true
78
87
  }, "Tab 3 content")))),
79
88
  container = _render.container;
80
- expect(container.firstChild).toBeInTheDocument();
89
+ const panels = container.querySelectorAll('[role="tabpanel"]');
90
+ expect(panels.length).toBe(3);
81
91
  });
82
- it('should render same content for other tabs as for the active one', () => {
92
+ it('should render with null children', async () => {
83
93
  const _render2 = render(_Tabs2 || (_Tabs2 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
94
+ renderTitle: "First Tab"
95
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
96
+ renderTitle: "Second Tab"
97
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
98
+ renderTitle: "Third Tab",
99
+ isDisabled: true
100
+ }, "Tab 3 content"), null))),
101
+ container = _render2.container;
102
+ const panels = container.querySelectorAll('[role="tabpanel"]');
103
+ expect(panels.length).toBe(3);
104
+ });
105
+ it('should be okay with rendering without any children', async () => {
106
+ render(_Tabs3 || (_Tabs3 = /*#__PURE__*/React.createElement(Tabs, null)));
107
+ expect(consoleErrorMock).not.toHaveBeenCalled();
108
+ });
109
+ it('should render correct number of tabs', async () => {
110
+ render(_Tabs4 || (_Tabs4 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
111
+ renderTitle: "First Tab"
112
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
113
+ renderTitle: "Second Tab"
114
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
115
+ renderTitle: "Third Tab",
116
+ isDisabled: true
117
+ }, "Tab 3 content"))));
118
+ const tabs = screen.getAllByRole('tab');
119
+ expect(tabs.length).toBe(3);
120
+ });
121
+ it('should render same content for other tabs as for the active one', () => {
122
+ const _render3 = render(_Tabs5 || (_Tabs5 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
84
123
  renderTitle: "First Tab",
85
124
  active: true
86
125
  }, "CONTENT"), /*#__PURE__*/React.createElement(Tabs.Panel, {
@@ -90,28 +129,30 @@ describe('<Tabs />', () => {
90
129
  }, "Child"), /*#__PURE__*/React.createElement(Tabs.Panel, {
91
130
  renderTitle: "Third Tab"
92
131
  }, "Child")))),
93
- container = _render2.container;
132
+ container = _render3.container;
94
133
  const tabContent = screen.getByText('CONTENT');
95
134
  expect(container).toBeInTheDocument();
96
135
  expect(tabContent).toBeInTheDocument();
97
136
  const childContent = screen.queryByText('Child');
98
137
  expect(childContent).toBeNull();
99
138
  });
100
- it('should render the same content in second tab when selected', () => {
139
+ it('should render the same content in second tab when selected', async () => {
101
140
  const onIndexChange = vi.fn();
102
- const _render3 = render(/*#__PURE__*/React.createElement(TabExample, {
141
+ const _render4 = render(/*#__PURE__*/React.createElement(TabExample, {
103
142
  onIndexChange: onIndexChange
104
143
  })),
105
- container = _render3.container;
144
+ container = _render4.container;
106
145
  expect(container).toBeInTheDocument();
107
146
  const secondTab = screen.getAllByRole('tab')[1];
108
- fireEvent.click(secondTab);
109
- expect(onIndexChange).toHaveBeenCalledWith(1);
147
+ await userEvent.click(secondTab);
148
+ await waitFor(() => {
149
+ expect(onIndexChange).toHaveBeenCalledWith(1);
150
+ });
110
151
  const panelContent = screen.queryByText('CONTENT');
111
152
  expect(panelContent).toBeInTheDocument();
112
153
  });
113
154
  it('should warn if multiple active tabs exist', () => {
114
- const _render4 = render(_Tabs3 || (_Tabs3 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
155
+ const _render5 = render(_Tabs6 || (_Tabs6 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
115
156
  renderTitle: "First Tab",
116
157
  active: true
117
158
  }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
@@ -121,8 +162,200 @@ describe('<Tabs />', () => {
121
162
  renderTitle: "Third Tab",
122
163
  isDisabled: true
123
164
  }, "Tab 3 content")))),
124
- container = _render4.container;
165
+ container = _render5.container;
125
166
  expect(container.firstChild).toBeInTheDocument();
126
167
  expect(consoleErrorMock.mock.calls[0][0]).toEqual('Warning: [Tabs] Only one Panel can be marked as active.');
127
168
  });
169
+ it('should default to selecting the first tab', async () => {
170
+ const _render6 = render(_Tabs7 || (_Tabs7 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
171
+ renderTitle: "First Tab"
172
+ }, tab1Content), /*#__PURE__*/React.createElement(Tabs.Panel, {
173
+ renderTitle: "Second Tab"
174
+ }, tab2Content), /*#__PURE__*/React.createElement(Tabs.Panel, {
175
+ renderTitle: "Third Tab",
176
+ isDisabled: true
177
+ }, tab3Content)))),
178
+ container = _render6.container;
179
+ const panelsContainer = container.querySelector('[class$="panelsContainer"]');
180
+ expect(panelsContainer).toHaveTextContent(tab1Content);
181
+ expect(screen.getByText(tab1Content)).toBeVisible();
182
+ expect(panelsContainer).not.toHaveTextContent(tab2Content);
183
+ expect(panelsContainer).not.toHaveTextContent(tab3Content);
184
+ });
185
+ it('should honor the isSelected prop', async () => {
186
+ const _render7 = render(_Tabs8 || (_Tabs8 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
187
+ renderTitle: "First Tab"
188
+ }, tab1Content), /*#__PURE__*/React.createElement(Tabs.Panel, {
189
+ renderTitle: "Second Tab",
190
+ isSelected: true
191
+ }, tab2Content), /*#__PURE__*/React.createElement(Tabs.Panel, {
192
+ renderTitle: "Third Tab",
193
+ isDisabled: true
194
+ }, tab3Content)))),
195
+ container = _render7.container;
196
+ const panelsContainer = container.querySelector('[class$="panelsContainer"]');
197
+ expect(panelsContainer).toHaveTextContent(tab2Content);
198
+ expect(screen.getByText(tab2Content)).toBeVisible();
199
+ expect(panelsContainer).not.toHaveTextContent(tab1Content);
200
+ expect(panelsContainer).not.toHaveTextContent(tab3Content);
201
+ });
202
+ it('should not allow selecting a disabled tab', async () => {
203
+ const _render8 = render(_Tabs9 || (_Tabs9 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
204
+ renderTitle: "First Tab"
205
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
206
+ renderTitle: "Second Tab"
207
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
208
+ renderTitle: "Third Tab",
209
+ isDisabled: true,
210
+ isSelected: true
211
+ }, "Tab 3 content")))),
212
+ container = _render8.container;
213
+ const panelsContainer = container.querySelector('[class$="panelsContainer"]');
214
+ const panels = container.querySelectorAll('[role="tabpanel"]');
215
+ expect(panelsContainer).toHaveTextContent(tab1Content);
216
+ expect(screen.getByText(tab1Content)).toBeVisible();
217
+ expect(panelsContainer).not.toHaveTextContent(tab2Content);
218
+ expect(panelsContainer).not.toHaveTextContent(tab3Content);
219
+ expect(panels.length).toBe(3);
220
+ expect(panels[0]).not.toHaveAttribute('aria-hidden', 'true');
221
+ expect(panels[1]).toHaveAttribute('aria-hidden', 'true');
222
+ expect(panels[2]).toHaveAttribute('aria-hidden', 'true');
223
+ });
224
+ it('should call onRequestTabChange when selection changes via click', async () => {
225
+ const onChange = vi.fn();
226
+ render(/*#__PURE__*/React.createElement(Tabs, {
227
+ onRequestTabChange: onChange
228
+ }, _Tabs$Panel || (_Tabs$Panel = /*#__PURE__*/React.createElement(Tabs.Panel, {
229
+ renderTitle: "First Tab",
230
+ isSelected: true,
231
+ id: "one"
232
+ }, "Tab 1 content")), _Tabs$Panel2 || (_Tabs$Panel2 = /*#__PURE__*/React.createElement(Tabs.Panel, {
233
+ renderTitle: "Second Tab",
234
+ id: "two"
235
+ }, "Tab 2 content")), _Tabs$Panel3 || (_Tabs$Panel3 = /*#__PURE__*/React.createElement(Tabs.Panel, {
236
+ renderTitle: "Third Tab",
237
+ isDisabled: true,
238
+ id: "three"
239
+ }, "Tab 3 content"))));
240
+ const secondTab = screen.getByText('Second Tab');
241
+ await userEvent.click(secondTab);
242
+ await waitFor(() => {
243
+ expect(onChange).toHaveBeenCalled();
244
+ const args = onChange.mock.calls[0][1];
245
+ expect(args).toHaveProperty('index', 1);
246
+ expect(args).toHaveProperty('id', 'two');
247
+ });
248
+ });
249
+ it('should focus the selected tab when shouldFocusOnRender is set', async () => {
250
+ render(_Tabs10 || (_Tabs10 = /*#__PURE__*/React.createElement(Tabs, {
251
+ shouldFocusOnRender: true
252
+ }, /*#__PURE__*/React.createElement(Tabs.Panel, {
253
+ renderTitle: "First Tab"
254
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
255
+ renderTitle: "Second Tab",
256
+ isSelected: true
257
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
258
+ renderTitle: "Third Tab",
259
+ isDisabled: true
260
+ }, "Tab 3 content"))));
261
+ const secondTab = screen.getByText('Second Tab');
262
+ await waitFor(() => {
263
+ expect(document.activeElement).toBe(secondTab);
264
+ });
265
+ });
266
+ it('should not call onRequestTabChange when clicking a disabled tab', async () => {
267
+ const onChange = vi.fn();
268
+ render(/*#__PURE__*/React.createElement(Tabs, {
269
+ onRequestTabChange: onChange
270
+ }, _Tabs$Panel4 || (_Tabs$Panel4 = /*#__PURE__*/React.createElement(Tabs.Panel, {
271
+ renderTitle: "First Tab"
272
+ }, "Tab 1 content")), _Tabs$Panel5 || (_Tabs$Panel5 = /*#__PURE__*/React.createElement(Tabs.Panel, {
273
+ renderTitle: "Second Tab"
274
+ }, "Tab 2 content")), _Tabs$Panel6 || (_Tabs$Panel6 = /*#__PURE__*/React.createElement(Tabs.Panel, {
275
+ renderTitle: "Third Tab",
276
+ isDisabled: true
277
+ }, "Tab 3 content"))));
278
+ const thirdTab = screen.getByText('Third Tab');
279
+ await userEvent.click(thirdTab);
280
+ await waitFor(() => {
281
+ expect(onChange).not.toHaveBeenCalled();
282
+ });
283
+ });
284
+ it('should meet a11y standards when set to the secondary variant', async () => {
285
+ const _render9 = render(_Tabs11 || (_Tabs11 = /*#__PURE__*/React.createElement(Tabs, {
286
+ variant: "secondary"
287
+ }, /*#__PURE__*/React.createElement(Tabs.Panel, {
288
+ renderTitle: "First Tab"
289
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
290
+ renderTitle: "Second Tab"
291
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
292
+ renderTitle: "Third Tab",
293
+ isDisabled: true
294
+ }, "Tab 3 content")))),
295
+ container = _render9.container;
296
+ const axeCheck = await runAxeCheck(container);
297
+ expect(axeCheck).toBe(true);
298
+ });
299
+ it('should meet a11y standards when set to the default variant', async () => {
300
+ const _render10 = render(_Tabs12 || (_Tabs12 = /*#__PURE__*/React.createElement(Tabs, {
301
+ variant: "default"
302
+ }, /*#__PURE__*/React.createElement(Tabs.Panel, {
303
+ renderTitle: "First Tab"
304
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
305
+ renderTitle: "Second Tab"
306
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
307
+ renderTitle: "Third Tab",
308
+ isDisabled: true
309
+ }, "Tab 3 content")))),
310
+ container = _render10.container;
311
+ const axeCheck = await runAxeCheck(container);
312
+ expect(axeCheck).toBe(true);
313
+ });
314
+ it('should link tabs with the corresponding panels via ids', async () => {
315
+ const _render11 = render(_Tabs13 || (_Tabs13 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
316
+ renderTitle: "First Tab"
317
+ }, "Tab 1 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
318
+ renderTitle: "Second Tab"
319
+ }, "Tab 2 content"), /*#__PURE__*/React.createElement(Tabs.Panel, {
320
+ renderTitle: "Third Tab",
321
+ isDisabled: true
322
+ }, "Tab 3 content")))),
323
+ container = _render11.container;
324
+ const firstTab = screen.getByText('First Tab');
325
+ const firstPanel = container.querySelectorAll('[role="tabpanel"]')[0];
326
+ expect(firstTab).toHaveAttribute('aria-controls', firstPanel.id);
327
+ expect(firstPanel).toHaveAttribute('aria-labelledby', firstTab.id);
328
+ });
329
+ describe('with duplicate-named tabs', () => {
330
+ it('should still render the correct number of panels', async () => {
331
+ const _render12 = render(_Tabs14 || (_Tabs14 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
332
+ renderTitle: "A Tab"
333
+ }, "Contents of first tab."), /*#__PURE__*/React.createElement(Tabs.Panel, {
334
+ renderTitle: "A Tab"
335
+ }, "Contents of second tab."), /*#__PURE__*/React.createElement(Tabs.Panel, {
336
+ renderTitle: "A Tab",
337
+ isDisabled: true
338
+ }, "Contents of third tab.")))),
339
+ container = _render12.container;
340
+ const tabPanels = container.querySelectorAll('[role="tabpanel"]');
341
+ expect(tabPanels.length).toBe(3);
342
+ });
343
+ });
344
+ describe('with nodes as tab titles', () => {
345
+ it('should still render the correct number of panels', async () => {
346
+ const _render13 = render(_Tabs15 || (_Tabs15 = /*#__PURE__*/React.createElement(Tabs, null, /*#__PURE__*/React.createElement(Tabs.Panel, {
347
+ renderTitle: /*#__PURE__*/React.createElement("div", null)
348
+ }, "Contents of first tab."), /*#__PURE__*/React.createElement(Tabs.Panel, {
349
+ renderTitle: /*#__PURE__*/React.createElement("span", null)
350
+ }, "Contents of second tab."), /*#__PURE__*/React.createElement(Tabs.Panel, {
351
+ renderTitle: /*#__PURE__*/React.createElement("img", {
352
+ alt: "example"
353
+ }),
354
+ isDisabled: true
355
+ }, "Contents of third tab.")))),
356
+ container = _render13.container;
357
+ const tabPanels = container.querySelectorAll('[role="tabpanel"]');
358
+ expect(tabPanels.length).toBe(3);
359
+ });
360
+ });
128
361
  });
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TabsLocator = void 0;
7
- var _locator = require("@instructure/ui-test-locator/lib/utils/locator.js");
8
- var _index = require("./index");
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _react = _interopRequireDefault(require("react"));
5
+ var _react2 = require("@testing-library/react");
6
+ require("@testing-library/jest-dom");
7
+ var _index = require("../index");
8
+ var _Panel, _Panel2;
9
9
  /*
10
10
  * The MIT License (MIT)
11
11
  *
@@ -29,26 +29,22 @@ var _index = require("./index");
29
29
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
30
  * SOFTWARE.
31
31
  */
32
-
33
- const TabLocator = (0, _locator.locator)('[role="tab"]');
34
- const PanelLocator = (0, _locator.locator)('[role="tabpanel"]');
35
- const SelectedTabLocator = (0, _locator.locator)('[role="tab"][aria-selected="true"]');
36
-
37
- // @ts-expect-error ts-migrate(2339) FIXME: Property 'selector' does not exist on type 'typeof... Remove this comment to see the full error message
38
- const TabsLocator = exports.TabsLocator = (0, _locator.locator)(_index.Tabs.selector, {
39
- findTab: (...args) => {
40
- return TabLocator.find(...args);
41
- },
42
- findAllTabs: (...args) => {
43
- return TabLocator.findAll(...args);
44
- },
45
- findSelectedTab: (...args) => {
46
- return SelectedTabLocator.find(...args);
47
- },
48
- findTabPanel: (...args) => {
49
- return PanelLocator.find(...args);
50
- },
51
- findAllTabPanels: (...args) => {
52
- return PanelLocator.findAll(...args);
53
- }
32
+ describe('<Tabs.Panel />', () => {
33
+ it('should render children', async () => {
34
+ (0, _react2.render)(_Panel || (_Panel = /*#__PURE__*/_react.default.createElement(_index.Panel, {
35
+ isSelected: true,
36
+ renderTitle: "Panel Title"
37
+ }, "Panel contents")));
38
+ const children = _react2.screen.getByText('Panel contents');
39
+ expect(children).toBeInTheDocument();
40
+ });
41
+ it('should have appropriate role attribute', async () => {
42
+ const _render = (0, _react2.render)(_Panel2 || (_Panel2 = /*#__PURE__*/_react.default.createElement(_index.Panel, {
43
+ isSelected: true,
44
+ renderTitle: "Panel Title"
45
+ }, "Panel contents"))),
46
+ container = _render.container;
47
+ const tabPanel = container.querySelector('[class$="-panel"]');
48
+ expect(tabPanel).toHaveAttribute('role', 'tabpanel');
49
+ });
54
50
  });