@instructure/ui-tree-browser 10.16.1 → 10.16.3

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/es/TreeBrowser/TreeButton/__new-tests__/TreeButton.test.js +165 -0
  3. package/es/TreeBrowser/TreeCollection/__new-tests__/TreeCollection.test.js +454 -0
  4. package/es/TreeBrowser/{TreeBrowserLocator.js → TreeNode/__new-tests__/TreeNode.test.js} +31 -14
  5. package/es/TreeBrowser/__new-tests__/TreeBrowser.test.js +525 -0
  6. package/lib/TreeBrowser/TreeButton/__new-tests__/TreeButton.test.js +166 -0
  7. package/lib/TreeBrowser/TreeCollection/__new-tests__/TreeCollection.test.js +457 -0
  8. package/lib/TreeBrowser/TreeNode/__new-tests__/TreeNode.test.js +56 -0
  9. package/lib/TreeBrowser/__new-tests__/TreeBrowser.test.js +527 -0
  10. package/package.json +17 -14
  11. package/src/TreeBrowser/TreeButton/__new-tests__/TreeButton.test.tsx +162 -0
  12. package/src/TreeBrowser/TreeCollection/__new-tests__/TreeCollection.test.tsx +423 -0
  13. package/src/TreeBrowser/{TreeBrowserLocator.ts → TreeNode/__new-tests__/TreeNode.test.tsx} +30 -13
  14. package/src/TreeBrowser/__new-tests__/TreeBrowser.test.tsx +575 -0
  15. package/tsconfig.build.json +1 -1
  16. package/tsconfig.build.tsbuildinfo +1 -1
  17. package/types/TreeBrowser/TreeButton/__new-tests__/TreeButton.test.d.ts +2 -0
  18. package/types/TreeBrowser/TreeButton/__new-tests__/TreeButton.test.d.ts.map +1 -0
  19. package/types/TreeBrowser/TreeCollection/__new-tests__/TreeCollection.test.d.ts +2 -0
  20. package/types/TreeBrowser/TreeCollection/__new-tests__/TreeCollection.test.d.ts.map +1 -0
  21. package/types/TreeBrowser/TreeNode/__new-tests__/TreeNode.test.d.ts +2 -0
  22. package/types/TreeBrowser/TreeNode/__new-tests__/TreeNode.test.d.ts.map +1 -0
  23. package/types/TreeBrowser/__new-tests__/TreeBrowser.test.d.ts +2 -0
  24. package/types/TreeBrowser/__new-tests__/TreeBrowser.test.d.ts.map +1 -0
  25. package/es/TreeBrowser/locator.js +0 -26
  26. package/lib/TreeBrowser/TreeBrowserLocator.js +0 -44
  27. package/lib/TreeBrowser/locator.js +0 -37
  28. package/src/TreeBrowser/locator.ts +0 -27
  29. package/types/TreeBrowser/TreeBrowserLocator.d.ts +0 -1065
  30. package/types/TreeBrowser/TreeBrowserLocator.d.ts.map +0 -1
  31. package/types/TreeBrowser/locator.d.ts +0 -4
  32. package/types/TreeBrowser/locator.d.ts.map +0 -1
@@ -0,0 +1,527 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _react = require("@testing-library/react");
5
+ var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
6
+ var _vitest = require("vitest");
7
+ var _runAxeCheck = require("@instructure/ui-axe-check/lib/runAxeCheck.js");
8
+ require("@testing-library/jest-dom");
9
+ var _index = require("../index");
10
+ var _TreeNode3 = require("../TreeNode");
11
+ var _jsxRuntime = require("@emotion/react/jsx-runtime");
12
+ var _TreeBrowser, _TreeBrowser2, _TreeBrowser3, _TreeBrowser4, _TreeBrowser5, _TreeBrowser6, _TreeBrowser7, _TreeBrowser8, _TreeBrowser9, _TreeBrowser10, _TreeBrowser11, _svg, _TreeBrowser12, _TreeNode, _TreeNode2, _svg2, _TreeBrowser13, _TreeBrowser14, _TreeBrowser15, _TreeBrowser16, _TreeBrowser17;
13
+ /*
14
+ * The MIT License (MIT)
15
+ *
16
+ * Copyright (c) 2015 - present Instructure, Inc.
17
+ *
18
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
19
+ * of this software and associated documentation files (the "Software"), to deal
20
+ * in the Software without restriction, including without limitation the rights
21
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22
+ * copies of the Software, and to permit persons to whom the Software is
23
+ * furnished to do so, subject to the following conditions:
24
+ *
25
+ * The above copyright notice and this permission notice shall be included in all
26
+ * copies or substantial portions of the Software.
27
+ *
28
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34
+ * SOFTWARE.
35
+ */
36
+ const COLLECTIONS_DATA = {
37
+ 2: {
38
+ id: 2,
39
+ name: 'Root Directory',
40
+ collections: [3, 4],
41
+ items: [1]
42
+ },
43
+ 3: {
44
+ id: 3,
45
+ name: 'Sub Root 1',
46
+ collections: [5]
47
+ },
48
+ 4: {
49
+ id: 4,
50
+ name: 'Sub Root 2'
51
+ },
52
+ 5: {
53
+ id: 5,
54
+ name: 'Nested Sub Collection'
55
+ }
56
+ };
57
+ const COLLECTIONS_DATA_WITH_ZERO = {
58
+ 0: {
59
+ id: 0,
60
+ name: 'Root Directory',
61
+ collections: [3, 4],
62
+ items: [1]
63
+ },
64
+ 3: {
65
+ id: 3,
66
+ name: 'Sub Root 1',
67
+ collections: [5]
68
+ },
69
+ 4: {
70
+ id: 4,
71
+ name: 'Sub Root 2'
72
+ },
73
+ 5: {
74
+ id: 5,
75
+ name: 'Nested Sub Collection'
76
+ }
77
+ };
78
+ const COLLECTIONS_DATA_WITH_STRING_IDS = {
79
+ '2': {
80
+ id: '2',
81
+ name: 'Root Directory',
82
+ collections: ['3', '4'],
83
+ items: [1]
84
+ },
85
+ '3': {
86
+ id: '3',
87
+ name: 'Sub Root 1',
88
+ collections: ['5']
89
+ },
90
+ '4': {
91
+ id: '4',
92
+ name: 'Sub Root 2'
93
+ },
94
+ '5': {
95
+ id: '5',
96
+ name: 'Nested Sub Collection'
97
+ }
98
+ };
99
+ const ITEMS_DATA = {
100
+ 1: {
101
+ id: 1,
102
+ name: 'Item 1'
103
+ }
104
+ };
105
+ describe('<TreeBrowser />', () => {
106
+ let consoleWarningMock;
107
+ let consoleErrorMock;
108
+ beforeEach(() => {
109
+ // Mocking console to prevent test output pollution and expect for messages
110
+ consoleWarningMock = _vitest.vi.spyOn(console, 'warn').mockImplementation(() => {});
111
+ consoleErrorMock = _vitest.vi.spyOn(console, 'error').mockImplementation(() => {});
112
+ });
113
+ afterEach(() => {
114
+ consoleWarningMock.mockRestore();
115
+ consoleErrorMock.mockRestore();
116
+ });
117
+ it('should render a tree', async () => {
118
+ const _render = (0, _react.render)(_TreeBrowser || (_TreeBrowser = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
119
+ collections: COLLECTIONS_DATA,
120
+ items: ITEMS_DATA,
121
+ rootId: 2
122
+ }))),
123
+ container = _render.container;
124
+ const tree = container.querySelector('[class$="-treeBrowser"]');
125
+ expect(tree).toBeInTheDocument();
126
+ });
127
+ it('should render subcollections', async () => {
128
+ (0, _react.render)(_TreeBrowser2 || (_TreeBrowser2 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
129
+ collections: COLLECTIONS_DATA,
130
+ items: ITEMS_DATA,
131
+ rootId: 2
132
+ })));
133
+ const items = _react.screen.getAllByRole('treeitem');
134
+ expect(items.length).toEqual(1);
135
+ await _userEvent.default.click(items[0]);
136
+ await (0, _react.waitFor)(() => {
137
+ const itemsAfterClick = _react.screen.getAllByRole('treeitem');
138
+ expect(itemsAfterClick.length).toEqual(4);
139
+ });
140
+ });
141
+ it('should render all collections at top level if showRootCollection is true and rootId is undefined', async () => {
142
+ (0, _react.render)(_TreeBrowser3 || (_TreeBrowser3 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
143
+ collections: COLLECTIONS_DATA,
144
+ items: ITEMS_DATA,
145
+ rootId: void 0
146
+ })));
147
+ const items = _react.screen.getAllByRole('treeitem');
148
+ expect(items.length).toEqual(4);
149
+ });
150
+ describe('expanded', () => {
151
+ it('should not expand collections or items without defaultExpanded prop', async () => {
152
+ (0, _react.render)(_TreeBrowser4 || (_TreeBrowser4 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
153
+ collections: COLLECTIONS_DATA,
154
+ items: ITEMS_DATA,
155
+ rootId: 2
156
+ })));
157
+ const items = _react.screen.getAllByRole('treeitem');
158
+ expect(items.length).toEqual(1);
159
+ expect(items[0]).toHaveTextContent('Root Directory');
160
+ });
161
+ it('should accept an array of default expanded collections', async () => {
162
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
163
+ collections: COLLECTIONS_DATA,
164
+ items: ITEMS_DATA,
165
+ rootId: 2,
166
+ defaultExpanded: [2, 3]
167
+ }));
168
+ const items = _react.screen.getAllByRole('treeitem');
169
+ const subRoot2 = _react.screen.getByLabelText('Sub Root 2');
170
+ const nestedSub = _react.screen.getByLabelText('Nested Sub Collection');
171
+ expect(items.length).toEqual(5);
172
+ expect(subRoot2).toHaveAttribute('aria-label', 'Sub Root 2');
173
+ expect(subRoot2).toHaveTextContent('Sub Root 2');
174
+ expect(nestedSub).toHaveAttribute('aria-label', 'Nested Sub Collection');
175
+ expect(nestedSub).toHaveTextContent('Nested Sub Collection');
176
+ });
177
+ });
178
+ describe('selected', () => {
179
+ it('should not show the selection if selectionType is none', async () => {
180
+ (0, _react.render)(_TreeBrowser5 || (_TreeBrowser5 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
181
+ collections: COLLECTIONS_DATA,
182
+ items: ITEMS_DATA,
183
+ rootId: 2
184
+ })));
185
+ const item = _react.screen.getByRole('treeitem');
186
+ await _userEvent.default.click(item);
187
+ await (0, _react.waitFor)(() => {
188
+ expect(item).not.toHaveAttribute('aria-selected');
189
+ });
190
+ });
191
+ it('should show the selection indicator on last clicked collection or item', async () => {
192
+ (0, _react.render)(_TreeBrowser6 || (_TreeBrowser6 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
193
+ collections: COLLECTIONS_DATA,
194
+ items: ITEMS_DATA,
195
+ rootId: 2,
196
+ selectionType: "single"
197
+ })));
198
+ const item = _react.screen.getByLabelText('Root Directory');
199
+ await _userEvent.default.click(item);
200
+ await (0, _react.waitFor)(() => {
201
+ expect(item).toHaveAttribute('aria-selected');
202
+ });
203
+ const nestedItem = _react.screen.getByLabelText('Item 1');
204
+ await _userEvent.default.click(nestedItem);
205
+ await (0, _react.waitFor)(() => {
206
+ expect(nestedItem).toHaveAttribute('aria-selected');
207
+ });
208
+ });
209
+ });
210
+ describe('collections', () => {
211
+ it('should render collections with string-keyed ids', async () => {
212
+ (0, _react.render)(_TreeBrowser7 || (_TreeBrowser7 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
213
+ collections: COLLECTIONS_DATA_WITH_STRING_IDS,
214
+ items: ITEMS_DATA,
215
+ rootId: '2',
216
+ showRootCollection: true
217
+ })));
218
+ const item = _react.screen.getByLabelText('Root Directory');
219
+ expect(item).toBeInTheDocument();
220
+ });
221
+ it('should not show the first keyed collection if showRootCollection is false', async () => {
222
+ (0, _react.render)(_TreeBrowser8 || (_TreeBrowser8 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
223
+ collections: COLLECTIONS_DATA,
224
+ items: ITEMS_DATA,
225
+ rootId: 2,
226
+ showRootCollection: false
227
+ })));
228
+ const items = _react.screen.getAllByRole('treeitem');
229
+ expect(items.length).toEqual(3);
230
+ });
231
+ it('should render first keyed collection if showRootCollection is true and rootId specified', async () => {
232
+ (0, _react.render)(_TreeBrowser9 || (_TreeBrowser9 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
233
+ collections: COLLECTIONS_DATA,
234
+ items: ITEMS_DATA,
235
+ rootId: 2
236
+ })));
237
+ const item = _react.screen.getByLabelText('Root Directory');
238
+ expect(item).toBeInTheDocument();
239
+ });
240
+ it('should not show the first keyed collection if showRootCollection is false and rootId is 0', async () => {
241
+ (0, _react.render)(_TreeBrowser10 || (_TreeBrowser10 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
242
+ collections: COLLECTIONS_DATA_WITH_ZERO,
243
+ items: ITEMS_DATA,
244
+ rootId: 0,
245
+ showRootCollection: false
246
+ })));
247
+ const items = _react.screen.getAllByRole('treeitem');
248
+ expect(items.length).toEqual(3);
249
+ });
250
+ it('should render a folder icon by default', async () => {
251
+ const _render2 = (0, _react.render)(_TreeBrowser11 || (_TreeBrowser11 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
252
+ collections: COLLECTIONS_DATA,
253
+ items: ITEMS_DATA,
254
+ rootId: 2
255
+ }))),
256
+ container = _render2.container;
257
+ const iconFolder = container.querySelectorAll('svg[name="IconFolder"]');
258
+ expect(iconFolder.length).toEqual(1);
259
+ });
260
+ it('should render a custom icon', async () => {
261
+ const IconCustom = _svg || (_svg = (0, _jsxRuntime.jsxs)("svg", {
262
+ height: "100",
263
+ width: "100",
264
+ "data-testid": "icon-custom",
265
+ children: [(0, _jsxRuntime.jsx)("title", {
266
+ "data-testid": "icon-custom-title",
267
+ children: "Custom icon"
268
+ }), (0, _jsxRuntime.jsx)("circle", {
269
+ cx: "50",
270
+ cy: "50",
271
+ r: "40"
272
+ })]
273
+ }));
274
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
275
+ collections: COLLECTIONS_DATA,
276
+ items: ITEMS_DATA,
277
+ rootId: 2,
278
+ collectionIcon: () => IconCustom
279
+ }));
280
+ const iconCustom = _react.screen.getByTestId('icon-custom');
281
+ const title = _react.screen.getByTestId('icon-custom-title');
282
+ expect(iconCustom).toBeInTheDocument();
283
+ expect(title).toBeInTheDocument();
284
+ expect(title).toHaveTextContent('Custom icon');
285
+ });
286
+ it('should render without icon if set to null', async () => {
287
+ const _render3 = (0, _react.render)(_TreeBrowser12 || (_TreeBrowser12 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
288
+ collections: COLLECTIONS_DATA,
289
+ items: ITEMS_DATA,
290
+ rootId: 2,
291
+ collectionIcon: null
292
+ }))),
293
+ container = _render3.container;
294
+ const icon = container.querySelector('svg');
295
+ expect(icon).not.toBeInTheDocument();
296
+ });
297
+ it('should call onCollectionToggle when expanding and collapsing with mouse', async () => {
298
+ const onCollectionToggle = _vitest.vi.fn();
299
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
300
+ collections: COLLECTIONS_DATA,
301
+ items: ITEMS_DATA,
302
+ rootId: 2,
303
+ onCollectionToggle: onCollectionToggle
304
+ }));
305
+ const item = _react.screen.getByRole('treeitem');
306
+ await _userEvent.default.click(item);
307
+ await (0, _react.waitFor)(() => {
308
+ expect(onCollectionToggle).toHaveBeenCalled();
309
+ });
310
+ });
311
+ it('should call onCollectionClick on button activation (space/enter or click)', async () => {
312
+ const onCollectionClick = _vitest.vi.fn();
313
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
314
+ collections: COLLECTIONS_DATA,
315
+ items: ITEMS_DATA,
316
+ rootId: 2,
317
+ onCollectionClick: onCollectionClick
318
+ }));
319
+ const item = _react.screen.getByLabelText('Root Directory');
320
+ await _userEvent.default.click(item);
321
+ await _userEvent.default.type(item, '{space}');
322
+ await _userEvent.default.type(item, '{enter}');
323
+ await (0, _react.waitFor)(() => {
324
+ expect(onCollectionClick).toHaveBeenCalledTimes(3);
325
+ });
326
+ });
327
+ it('should render before, after nodes of the provided collection', async () => {
328
+ const _render4 = (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
329
+ collections: {
330
+ 2: {
331
+ id: 2,
332
+ name: 'Root Directory',
333
+ collections: [],
334
+ items: [],
335
+ renderBeforeItems: _TreeNode || (_TreeNode = (0, _jsxRuntime.jsx)(_TreeNode3.TreeNode, {
336
+ children: (0, _jsxRuntime.jsx)("input", {
337
+ id: "input-before"
338
+ })
339
+ })),
340
+ renderAfterItems: _TreeNode2 || (_TreeNode2 = (0, _jsxRuntime.jsx)(_TreeNode3.TreeNode, {
341
+ children: (0, _jsxRuntime.jsx)("input", {
342
+ id: "input-after"
343
+ })
344
+ }))
345
+ }
346
+ },
347
+ items: {},
348
+ expanded: [2],
349
+ rootId: 2
350
+ })),
351
+ container = _render4.container;
352
+ const contentBefore = container.querySelector('#input-before');
353
+ const contentAfter = container.querySelector('#input-after');
354
+ expect(contentBefore).toBeInTheDocument();
355
+ expect(contentAfter).toBeInTheDocument();
356
+ });
357
+ });
358
+ describe('items', () => {
359
+ it('should render a document icon by default', async () => {
360
+ const _render5 = (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
361
+ collections: COLLECTIONS_DATA,
362
+ items: ITEMS_DATA,
363
+ rootId: 2,
364
+ defaultExpanded: [2]
365
+ })),
366
+ container = _render5.container;
367
+ const iconDocument = container.querySelectorAll('svg[name="IconDocument"]');
368
+ expect(iconDocument.length).toEqual(1);
369
+ });
370
+ it('should render a custom icon', async () => {
371
+ const IconCustom = _svg2 || (_svg2 = (0, _jsxRuntime.jsxs)("svg", {
372
+ height: "100",
373
+ width: "100",
374
+ "data-testid": "icon-custom",
375
+ children: [(0, _jsxRuntime.jsx)("title", {
376
+ "data-testid": "icon-custom-title",
377
+ children: "Custom icon"
378
+ }), (0, _jsxRuntime.jsx)("circle", {
379
+ cx: "50",
380
+ cy: "50",
381
+ r: "40"
382
+ })]
383
+ }));
384
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
385
+ collections: COLLECTIONS_DATA,
386
+ items: ITEMS_DATA,
387
+ rootId: 2,
388
+ defaultExpanded: [2],
389
+ itemIcon: () => IconCustom
390
+ }));
391
+ const iconCustom = _react.screen.getByTestId('icon-custom');
392
+ const title = _react.screen.getByTestId('icon-custom-title');
393
+ expect(iconCustom).toBeInTheDocument();
394
+ expect(title).toBeInTheDocument();
395
+ expect(title).toHaveTextContent('Custom icon');
396
+ });
397
+ it('should render without icon if set to null', async () => {
398
+ const _render6 = (0, _react.render)(_TreeBrowser13 || (_TreeBrowser13 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
399
+ collections: COLLECTIONS_DATA,
400
+ items: ITEMS_DATA,
401
+ rootId: 2
402
+ }))),
403
+ container = _render6.container;
404
+ const iconDocument = container.querySelector('svg[name="IconDocument"]');
405
+ expect(iconDocument).not.toBeInTheDocument();
406
+ });
407
+ });
408
+ describe('for a11y', () => {
409
+ it('should meet a11y standards', async () => {
410
+ const _render7 = (0, _react.render)(_TreeBrowser14 || (_TreeBrowser14 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
411
+ collections: COLLECTIONS_DATA,
412
+ items: ITEMS_DATA,
413
+ rootId: 2
414
+ }))),
415
+ container = _render7.container;
416
+ const axeCheck = await (0, _runAxeCheck.runAxeCheck)(container);
417
+ expect(axeCheck).toBe(true);
418
+ });
419
+ it('should accept a treeLabel prop', async () => {
420
+ (0, _react.render)(_TreeBrowser15 || (_TreeBrowser15 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
421
+ collections: COLLECTIONS_DATA,
422
+ items: ITEMS_DATA,
423
+ rootId: 2,
424
+ treeLabel: "Test treeLabel"
425
+ })));
426
+ const tree = _react.screen.getByLabelText('Test treeLabel');
427
+ expect(tree).toBeInTheDocument();
428
+ });
429
+ it('should toggle aria-expanded', async () => {
430
+ (0, _react.render)(_TreeBrowser16 || (_TreeBrowser16 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
431
+ collections: COLLECTIONS_DATA,
432
+ items: ITEMS_DATA,
433
+ rootId: 2
434
+ })));
435
+ const item = _react.screen.getByRole('treeitem');
436
+ expect(item).toHaveAttribute('aria-expanded', 'false');
437
+ await _userEvent.default.click(item);
438
+ await (0, _react.waitFor)(() => {
439
+ expect(item).toHaveAttribute('aria-expanded', 'true');
440
+ });
441
+ });
442
+ it('should use aria-selected when selectionType is not none', async () => {
443
+ (0, _react.render)(_TreeBrowser17 || (_TreeBrowser17 = (0, _jsxRuntime.jsx)(_index.TreeBrowser, {
444
+ collections: COLLECTIONS_DATA,
445
+ items: ITEMS_DATA,
446
+ rootId: 2,
447
+ selectionType: "single"
448
+ })));
449
+ const item = _react.screen.getByRole('treeitem');
450
+ expect(item).not.toHaveAttribute('aria-selected');
451
+ await _userEvent.default.click(item);
452
+ await (0, _react.waitFor)(() => {
453
+ expect(item).toHaveAttribute('aria-selected', 'true');
454
+ });
455
+ const nestedItem = _react.screen.getByLabelText('Sub Root 1');
456
+ expect(nestedItem).toHaveAttribute('aria-selected', 'false');
457
+ });
458
+ });
459
+ describe('sorting', () => {
460
+ it("should present collections and items in alphabetical order, in spite of the order of 'collections' and 'items' arrays", async () => {
461
+ (0, _react.render)((0, _jsxRuntime.jsx)(_index.TreeBrowser, {
462
+ collections: {
463
+ 1: {
464
+ id: 1,
465
+ name: 'Assignments',
466
+ collections: [5, 3, 2, 4],
467
+ items: [3, 5, 2, 1, 4]
468
+ },
469
+ 2: {
470
+ id: 2,
471
+ name: 'English Assignments',
472
+ collections: [],
473
+ items: []
474
+ },
475
+ 3: {
476
+ id: 3,
477
+ name: 'Math Assignments',
478
+ collections: [],
479
+ items: []
480
+ },
481
+ 4: {
482
+ id: 4,
483
+ name: 'Reading Assignments',
484
+ collections: [],
485
+ items: []
486
+ },
487
+ 5: {
488
+ id: 5,
489
+ name: 'Advanced Math Assignments',
490
+ items: []
491
+ }
492
+ },
493
+ items: {
494
+ 1: {
495
+ id: 1,
496
+ name: 'Addition Worksheet'
497
+ },
498
+ 2: {
499
+ id: 2,
500
+ name: 'Subtraction Worksheet'
501
+ },
502
+ 3: {
503
+ id: 3,
504
+ name: 'General Questions'
505
+ },
506
+ 4: {
507
+ id: 4,
508
+ name: 'Vogon Poetry'
509
+ },
510
+ 5: {
511
+ id: 5,
512
+ name: 'Bistromath'
513
+ }
514
+ },
515
+ rootId: 1,
516
+ defaultExpanded: [1],
517
+ sortOrder: (a, b) => {
518
+ return a.name.localeCompare(b.name);
519
+ }
520
+ }));
521
+ const items = _react.screen.getAllByRole('treeitem');
522
+ const arr = items.map(item => item.textContent);
523
+ expect(arr.slice(1, 5)).toStrictEqual(['Advanced Math Assignments', 'English Assignments', 'Math Assignments', 'Reading Assignments']);
524
+ expect(arr.slice(5)).toStrictEqual(['Addition Worksheet', 'Bistromath', 'General Questions', 'Subtraction Worksheet', 'Vogon Poetry']);
525
+ });
526
+ });
527
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-tree-browser",
3
- "version": "10.16.1",
3
+ "version": "10.16.3",
4
4
  "description": "A component for displaying a hierarchical view of information",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -23,22 +23,25 @@
23
23
  },
24
24
  "license": "MIT",
25
25
  "devDependencies": {
26
- "@instructure/ui-babel-preset": "10.16.1",
27
- "@instructure/ui-color-utils": "10.16.1",
28
- "@instructure/ui-test-locator": "10.16.1",
29
- "@instructure/ui-test-utils": "10.16.1",
30
- "@instructure/ui-themes": "10.16.1"
26
+ "@instructure/ui-axe-check": "10.16.3",
27
+ "@instructure/ui-babel-preset": "10.16.3",
28
+ "@instructure/ui-color-utils": "10.16.3",
29
+ "@instructure/ui-test-utils": "10.16.3",
30
+ "@instructure/ui-themes": "10.16.3",
31
+ "@testing-library/jest-dom": "^6.6.3",
32
+ "@testing-library/react": "^16.0.1",
33
+ "vitest": "^2.1.8"
31
34
  },
32
35
  "dependencies": {
33
36
  "@babel/runtime": "^7.26.0",
34
- "@instructure/emotion": "10.16.1",
35
- "@instructure/shared-types": "10.16.1",
36
- "@instructure/ui-icons": "10.16.1",
37
- "@instructure/ui-img": "10.16.1",
38
- "@instructure/ui-prop-types": "10.16.1",
39
- "@instructure/ui-react-utils": "10.16.1",
40
- "@instructure/ui-testable": "10.16.1",
41
- "@instructure/ui-utils": "10.16.1",
37
+ "@instructure/emotion": "10.16.3",
38
+ "@instructure/shared-types": "10.16.3",
39
+ "@instructure/ui-icons": "10.16.3",
40
+ "@instructure/ui-img": "10.16.3",
41
+ "@instructure/ui-prop-types": "10.16.3",
42
+ "@instructure/ui-react-utils": "10.16.3",
43
+ "@instructure/ui-testable": "10.16.3",
44
+ "@instructure/ui-utils": "10.16.3",
42
45
  "keycode": "^2",
43
46
  "prop-types": "^15.8.1"
44
47
  },