@spectrum-web-components/sidenav 0.12.7 → 0.12.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/sidenav",
3
- "version": "0.12.7",
3
+ "version": "0.12.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@spectrum-web-components/base": "^0.5.4",
52
52
  "@spectrum-web-components/reactive-controllers": "^0.2.2",
53
- "@spectrum-web-components/shared": "^0.13.6",
53
+ "@spectrum-web-components/shared": "^0.13.7",
54
54
  "tslib": "^2.0.0"
55
55
  },
56
56
  "devDependencies": {
@@ -61,5 +61,5 @@
61
61
  "sideEffects": [
62
62
  "./sp-*.js"
63
63
  ],
64
- "gitHead": "caf12727e7f91dcf961e1fadacc727eea9ece27b"
64
+ "gitHead": "dd76f9532fdea946880147cc7645f113b998c326"
65
65
  }
@@ -0,0 +1,91 @@
1
+ /*
2
+ Copyright 2020 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import '@spectrum-web-components/sidenav/sp-sidenav.js';
13
+ import '@spectrum-web-components/sidenav/sp-sidenav-item.js';
14
+ import '@spectrum-web-components/sidenav/sp-sidenav-heading.js';
15
+ import { html } from 'lit';
16
+ import { measureFixtureCreation } from '../../../../test/benchmark/helpers.js';
17
+ measureFixtureCreation(html `
18
+ <sp-sidenav manage-tab-index>
19
+ <sp-sidenav-item value="Section 1" label="Section 1"></sp-sidenav-item>
20
+ <sp-sidenav-item selected expanded value="Section 2" label="Section 2">
21
+ <sp-sidenav-item
22
+ value="Section 2a"
23
+ label="Section 2a"
24
+ ></sp-sidenav-item>
25
+ <sp-sidenav-item
26
+ value="Section 2b"
27
+ label="Section 2b"
28
+ ></sp-sidenav-item>
29
+ <sp-sidenav-item
30
+ value="Section 2c"
31
+ label="Section 2c"
32
+ ></sp-sidenav-item>
33
+ </sp-sidenav-item>
34
+ <sp-sidenav-heading label="CATEGORY 1">
35
+ <sp-sidenav-item
36
+ value="Section 3"
37
+ label="Section 3"
38
+ ></sp-sidenav-item>
39
+ <sp-sidenav-item value="Section 4" label="Section 4">
40
+ <sp-sidenav-item
41
+ value="Section 4a"
42
+ label="Section 4a"
43
+ ></sp-sidenav-item>
44
+ <sp-sidenav-item
45
+ value="Section 4b"
46
+ label="Section 4b"
47
+ ></sp-sidenav-item>
48
+ <sp-sidenav-item
49
+ value="Section 4c"
50
+ label="Section 4c"
51
+ ></sp-sidenav-item>
52
+ </sp-sidenav-item>
53
+ </sp-sidenav-heading>
54
+ <sp-sidenav-item value="Section 1" label="Section 1"></sp-sidenav-item>
55
+ <sp-sidenav-item selected expanded value="Section 2" label="Section 2">
56
+ <sp-sidenav-item
57
+ value="Section 2a"
58
+ label="Section 2a"
59
+ ></sp-sidenav-item>
60
+ <sp-sidenav-item
61
+ value="Section 2b"
62
+ label="Section 2b"
63
+ ></sp-sidenav-item>
64
+ <sp-sidenav-item
65
+ value="Section 2c"
66
+ label="Section 2c"
67
+ ></sp-sidenav-item>
68
+ </sp-sidenav-item>
69
+ <sp-sidenav-heading label="CATEGORY 1">
70
+ <sp-sidenav-item
71
+ value="Section 3"
72
+ label="Section 3"
73
+ ></sp-sidenav-item>
74
+ <sp-sidenav-item value="Section 4" label="Section 4">
75
+ <sp-sidenav-item
76
+ value="Section 4a"
77
+ label="Section 4a"
78
+ ></sp-sidenav-item>
79
+ <sp-sidenav-item
80
+ value="Section 4b"
81
+ label="Section 4b"
82
+ ></sp-sidenav-item>
83
+ <sp-sidenav-item
84
+ value="Section 4c"
85
+ label="Section 4c"
86
+ ></sp-sidenav-item>
87
+ </sp-sidenav-item>
88
+ </sp-sidenav-heading>
89
+ </sp-sidenav>
90
+ `);
91
+ //# sourceMappingURL=test-basic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-basic.js","sourceRoot":"","sources":["test-basic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AAEF,OAAO,gDAAgD,CAAC;AACxD,OAAO,qDAAqD,CAAC;AAC7D,OAAO,wDAAwD,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,sBAAsB,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyE1B,CAAC,CAAC","sourcesContent":["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport '@spectrum-web-components/sidenav/sp-sidenav.js';\nimport '@spectrum-web-components/sidenav/sp-sidenav-item.js';\nimport '@spectrum-web-components/sidenav/sp-sidenav-heading.js';\nimport { html } from 'lit';\nimport { measureFixtureCreation } from '../../../../test/benchmark/helpers.js';\n\nmeasureFixtureCreation(html`\n <sp-sidenav manage-tab-index>\n <sp-sidenav-item value=\"Section 1\" label=\"Section 1\"></sp-sidenav-item>\n <sp-sidenav-item selected expanded value=\"Section 2\" label=\"Section 2\">\n <sp-sidenav-item\n value=\"Section 2a\"\n label=\"Section 2a\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2b\"\n label=\"Section 2b\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2c\"\n label=\"Section 2c\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n <sp-sidenav-heading label=\"CATEGORY 1\">\n <sp-sidenav-item\n value=\"Section 3\"\n label=\"Section 3\"\n ></sp-sidenav-item>\n <sp-sidenav-item value=\"Section 4\" label=\"Section 4\">\n <sp-sidenav-item\n value=\"Section 4a\"\n label=\"Section 4a\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 4b\"\n label=\"Section 4b\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 4c\"\n label=\"Section 4c\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n </sp-sidenav-heading>\n <sp-sidenav-item value=\"Section 1\" label=\"Section 1\"></sp-sidenav-item>\n <sp-sidenav-item selected expanded value=\"Section 2\" label=\"Section 2\">\n <sp-sidenav-item\n value=\"Section 2a\"\n label=\"Section 2a\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2b\"\n label=\"Section 2b\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2c\"\n label=\"Section 2c\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n <sp-sidenav-heading label=\"CATEGORY 1\">\n <sp-sidenav-item\n value=\"Section 3\"\n label=\"Section 3\"\n ></sp-sidenav-item>\n <sp-sidenav-item value=\"Section 4\" label=\"Section 4\">\n <sp-sidenav-item\n value=\"Section 4a\"\n label=\"Section 4a\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 4b\"\n label=\"Section 4b\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 4c\"\n label=\"Section 4c\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n </sp-sidenav-heading>\n </sp-sidenav>\n`);\n"]}
@@ -0,0 +1,95 @@
1
+ /*
2
+ Copyright 2020 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import '../sp-sidenav.js';
13
+ import '../sp-sidenav-item.js';
14
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
15
+ describe('Sidenav Item', () => {
16
+ it('can exist disabled and with no parent', async () => {
17
+ let selected = false;
18
+ const onSidenavSelect = () => {
19
+ selected = true;
20
+ };
21
+ const el = await fixture(html `
22
+ <sp-sidenav-item
23
+ disabled
24
+ value="Section 2"
25
+ label="Section 2"
26
+ @sidenav-select=${onSidenavSelect}
27
+ ></sp-sidenav-item>
28
+ `);
29
+ await elementUpdated(el);
30
+ expect(selected).to.be.false;
31
+ el.click();
32
+ await elementUpdated(el);
33
+ expect(selected).to.be.false;
34
+ el.disabled = false;
35
+ el.click();
36
+ await elementUpdated(el);
37
+ expect(selected).to.be.true;
38
+ });
39
+ it('clicking expands a sidenav item with children', async () => {
40
+ const el = await fixture(html `
41
+ <sp-sidenav-item>
42
+ <sp-sidenav-item
43
+ value="Section 1"
44
+ label="Section 1"
45
+ ></sp-sidenav-item>
46
+ <sp-sidenav-item
47
+ value="Section 2"
48
+ label="Section 2"
49
+ ></sp-sidenav-item>
50
+ </sp-sidenav-item>
51
+ `);
52
+ await elementUpdated(el);
53
+ expect(el.shadowRoot).to.exist;
54
+ if (!el.shadowRoot)
55
+ return;
56
+ let slot = el.shadowRoot.querySelector('slot[name="descendant"]');
57
+ expect(slot).not.to.exist;
58
+ expect(el.expanded).to.be.false;
59
+ el.click();
60
+ await elementUpdated(el);
61
+ expect(el.expanded).to.be.true;
62
+ slot = el.shadowRoot.querySelector('slot[name="descendant"]');
63
+ expect(slot).to.exist;
64
+ if (!slot)
65
+ return;
66
+ expect(slot.assignedElements().length).to.equal(2);
67
+ });
68
+ it('populated `aria-current`', async () => {
69
+ const el = await fixture(html `
70
+ <sp-sidenav value="Section 2">
71
+ <sp-sidenav-item
72
+ href="https://opensource.adobe.com/spectrum-web-components/"
73
+ label="Section 1"
74
+ value="Section 1"
75
+ ></sp-sidenav-item>
76
+ <sp-sidenav-item
77
+ href=${window.location.href}
78
+ label="Section 2"
79
+ value="Section 2"
80
+ selected
81
+ ></sp-sidenav-item>
82
+ </sp-sidenav>
83
+ `);
84
+ await elementUpdated(el);
85
+ const currentItem = el.querySelector('sp-sidenav-item:nth-child(2)');
86
+ const otherItem = el.querySelector('sp-sidenav-item:nth-child(1)');
87
+ await elementUpdated(currentItem);
88
+ await elementUpdated(otherItem);
89
+ expect(currentItem.focusElement.hasAttribute('aria-current'), 'current')
90
+ .to.be.true;
91
+ expect(otherItem.focusElement.hasAttribute('aria-current'), 'other').to
92
+ .be.false;
93
+ });
94
+ });
95
+ //# sourceMappingURL=sidenav-item.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidenav-item.test.js","sourceRoot":"","sources":["sidenav-item.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport '../sp-sidenav.js';\nimport '../sp-sidenav-item.js';\nimport { SideNavItem } from '../';\nimport { elementUpdated, expect, fixture, html } from '@open-wc/testing';\n\ndescribe('Sidenav Item', () => {\n it('can exist disabled and with no parent', async () => {\n let selected = false;\n const onSidenavSelect = (): void => {\n selected = true;\n };\n const el = await fixture<SideNavItem>(\n html`\n <sp-sidenav-item\n disabled\n value=\"Section 2\"\n label=\"Section 2\"\n @sidenav-select=${onSidenavSelect}\n ></sp-sidenav-item>\n `\n );\n\n await elementUpdated(el);\n\n expect(selected).to.be.false;\n\n el.click();\n\n await elementUpdated(el);\n\n expect(selected).to.be.false;\n\n el.disabled = false;\n\n el.click();\n\n await elementUpdated(el);\n\n expect(selected).to.be.true;\n });\n\n it('clicking expands a sidenav item with children', async () => {\n const el = await fixture<SideNavItem>(\n html`\n <sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2\"\n label=\"Section 2\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n `\n );\n\n await elementUpdated(el);\n\n expect(el.shadowRoot).to.exist;\n if (!el.shadowRoot) return;\n\n let slot: HTMLSlotElement | null = el.shadowRoot.querySelector(\n 'slot[name=\"descendant\"]'\n );\n expect(slot).not.to.exist;\n\n expect(el.expanded).to.be.false;\n\n el.click();\n\n await elementUpdated(el);\n\n expect(el.expanded).to.be.true;\n\n slot = el.shadowRoot.querySelector(\n 'slot[name=\"descendant\"]'\n ) as HTMLSlotElement;\n expect(slot).to.exist;\n if (!slot) return;\n\n expect(slot.assignedElements().length).to.equal(2);\n });\n\n it('populated `aria-current`', async () => {\n const el = await fixture<SideNavItem>(\n html`\n <sp-sidenav value=\"Section 2\">\n <sp-sidenav-item\n href=\"https://opensource.adobe.com/spectrum-web-components/\"\n label=\"Section 1\"\n value=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n href=${window.location.href}\n label=\"Section 2\"\n value=\"Section 2\"\n selected\n ></sp-sidenav-item>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n const currentItem = el.querySelector(\n 'sp-sidenav-item:nth-child(2)'\n ) as SideNavItem;\n const otherItem = el.querySelector(\n 'sp-sidenav-item:nth-child(1)'\n ) as SideNavItem;\n\n await elementUpdated(currentItem);\n await elementUpdated(otherItem);\n\n expect(currentItem.focusElement.hasAttribute('aria-current'), 'current')\n .to.be.true;\n expect(otherItem.focusElement.hasAttribute('aria-current'), 'other').to\n .be.false;\n });\n});\n"]}
@@ -0,0 +1,15 @@
1
+ /*
2
+ Copyright 2020 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import * as stories from '../stories/sidenav.stories.js';
13
+ import { regressVisuals } from '../../../test/visual/test.js';
14
+ regressVisuals('SidenavStories', stories);
15
+ //# sourceMappingURL=sidenav.test-vrt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidenav.test-vrt.js","sourceRoot":"","sources":["sidenav.test-vrt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AAEF,OAAO,KAAK,OAAO,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,cAAc,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC","sourcesContent":["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport * as stories from '../stories/sidenav.stories.js';\nimport { regressVisuals } from '../../../test/visual/test.js';\n\nregressVisuals('SidenavStories', stories);\n"]}
@@ -0,0 +1,365 @@
1
+ /*
2
+ Copyright 2020 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import '../sp-sidenav.js';
13
+ import '../sp-sidenav-item.js';
14
+ import '../sp-sidenav-heading.js';
15
+ import { SideNavItem } from '../';
16
+ import { manageTabIndex } from '../stories/sidenav.stories.js';
17
+ import { arrowDownEvent, arrowUpEvent, shiftTabEvent, } from '../../../test/testing-helpers.js';
18
+ import { elementUpdated, expect, fixture, html, waitUntil, } from '@open-wc/testing';
19
+ import { LitElement } from '@spectrum-web-components/base';
20
+ import { spy } from 'sinon';
21
+ import { sendMouse } from '../../../test/plugins/browser.js';
22
+ describe('Sidenav', () => {
23
+ it('loads', async () => {
24
+ const el = await fixture(html `
25
+ <sp-sidenav>
26
+ <sp-sidenav-heading label="CATEGORY 1">
27
+ <sp-sidenav-item
28
+ value="Section 1"
29
+ label="Section 1"
30
+ ></sp-sidenav-item>
31
+ <sp-sidenav-item
32
+ value="Section 2"
33
+ label="Section 2"
34
+ ></sp-sidenav-item>
35
+ </sp-sidenav-heading>
36
+ </sp-sidenav>
37
+ `);
38
+ await elementUpdated(el);
39
+ await expect(el).to.be.accessible();
40
+ });
41
+ it('does not accept focus/click/blur when empty', async () => {
42
+ const el = await fixture(html `
43
+ <sp-sidenav></sp-sidenav>
44
+ `);
45
+ await elementUpdated(el);
46
+ expect(document.activeElement === el).to.be.false;
47
+ el.focus();
48
+ await elementUpdated(el);
49
+ expect(document.activeElement === el).to.be.false;
50
+ el.blur();
51
+ await elementUpdated(el);
52
+ expect(document.activeElement === el).to.be.false;
53
+ el.click();
54
+ await elementUpdated(el);
55
+ expect(document.activeElement === el).to.be.false;
56
+ });
57
+ it('does not accept keyboard events when items are not present', async () => {
58
+ const errorSpy = spy();
59
+ const el = await fixture(html `
60
+ <sp-sidenav>
61
+ <sp-sidenav-item
62
+ value="Section 1"
63
+ label="Section 1"
64
+ ></sp-sidenav-item>
65
+ </sp-sidenav>
66
+ `);
67
+ await elementUpdated(el);
68
+ const item = el.querySelector('sp-sidenav-item');
69
+ window.addEventListener('error', () => errorSpy());
70
+ el.dispatchEvent(new FocusEvent('focusin'));
71
+ item.remove();
72
+ await elementUpdated(el);
73
+ el.dispatchEvent(new KeyboardEvent('keydown', {
74
+ code: 'ArrowDown',
75
+ }));
76
+ expect(errorSpy.callCount).to.equal(0);
77
+ });
78
+ it('does not accept focus when all children [disabled]', async () => {
79
+ const el = await fixture(html `
80
+ <sp-sidenav>
81
+ <sp-sidenav-item
82
+ disabled
83
+ value="Section 1"
84
+ label="Section 1"
85
+ ></sp-sidenav-item>
86
+ <sp-sidenav-item
87
+ disabled
88
+ value="Section 2"
89
+ label="Section 2"
90
+ ></sp-sidenav-item>
91
+ </sp-sidenav>
92
+ `);
93
+ await elementUpdated(el);
94
+ expect(document.activeElement === el).to.be.false;
95
+ el.focus();
96
+ await elementUpdated(el);
97
+ expect(document.activeElement === el).to.be.false;
98
+ expect(el.matches(':focus-within')).to.be.false;
99
+ });
100
+ it('sets manageTabIndex on new children', async () => {
101
+ const el = await fixture(html `
102
+ <sp-sidenav>
103
+ <sp-sidenav-item
104
+ value="Section 1"
105
+ label="Section 1"
106
+ ></sp-sidenav-item>
107
+ <sp-sidenav-item
108
+ value="Section 2"
109
+ label="Section 2"
110
+ ></sp-sidenav-item>
111
+ </sp-sidenav>
112
+ `);
113
+ await elementUpdated(el);
114
+ expect(el.manageTabIndex).to.be.false;
115
+ const item1 = el.querySelector('sp-sidenav-item');
116
+ expect(item1.tabIndex).to.equal(0);
117
+ const newItem = document.createElement('sp-sidenav-item');
118
+ newItem.value = 'Section 3';
119
+ newItem.label = 'Section 3';
120
+ el.appendChild(newItem);
121
+ await elementUpdated(newItem);
122
+ expect(newItem.tabIndex).to.equal(0);
123
+ el.focus();
124
+ const focused = document.activeElement;
125
+ focused.click();
126
+ expect(focused.selected).to.be.true;
127
+ el.dispatchEvent(shiftTabEvent());
128
+ const outsideFocused = document.activeElement;
129
+ expect(typeof outsideFocused).not.to.equal(SideNavItem);
130
+ });
131
+ it('handles select', async () => {
132
+ const changeSpy = spy();
133
+ const el = await fixture(html `
134
+ <sp-sidenav @change=${() => changeSpy()}>
135
+ <sp-sidenav-heading label="CATEGORY 1">
136
+ <sp-sidenav-item
137
+ value="Section 1"
138
+ label="Section 1"
139
+ ></sp-sidenav-item>
140
+ <sp-sidenav-item value="Section 2" label="Section 2">
141
+ <sp-sidenav-item
142
+ value="Section 2a"
143
+ label="Section 2a"
144
+ ></sp-sidenav-item>
145
+ </sp-sidenav-item>
146
+ </sp-sidenav-heading>
147
+ </sp-sidenav>
148
+ `);
149
+ await elementUpdated(el);
150
+ expect(el.value).to.be.undefined;
151
+ const sidenavItem = el.querySelector('[value="Section 2"]');
152
+ sidenavItem.dispatchEvent(new CustomEvent('sidenav-select', {
153
+ bubbles: true,
154
+ detail: {
155
+ value: 'Section 2',
156
+ },
157
+ }));
158
+ await elementUpdated(el);
159
+ expect(el.value).to.equal('Section 2');
160
+ expect(changeSpy.callCount).to.equal(1);
161
+ sidenavItem.click();
162
+ await elementUpdated(sidenavItem);
163
+ const sidenavItemChild = el.querySelector('[value="Section 2a"]');
164
+ sidenavItemChild.click();
165
+ await elementUpdated(el);
166
+ expect(el.value).to.equal('Section 2a');
167
+ expect(changeSpy.callCount).to.equal(2);
168
+ });
169
+ it('prevents selection', async () => {
170
+ const changeSpy = spy();
171
+ const el = await fixture(html `
172
+ <sp-sidenav
173
+ @change=${(event) => {
174
+ event.preventDefault();
175
+ changeSpy();
176
+ }}
177
+ >
178
+ <sp-sidenav-heading label="CATEGORY 1">
179
+ <sp-sidenav-item
180
+ value="Section 1"
181
+ label="Section 1"
182
+ ></sp-sidenav-item>
183
+ <sp-sidenav-item
184
+ value="Section 2"
185
+ label="Section 2"
186
+ opened
187
+ >
188
+ <sp-sidenav-item
189
+ value="Section 2a"
190
+ label="Section 2a"
191
+ ></sp-sidenav-item>
192
+ </sp-sidenav-item>
193
+ </sp-sidenav-heading>
194
+ </sp-sidenav>
195
+ `);
196
+ await elementUpdated(el);
197
+ expect(el.value).to.be.undefined;
198
+ el.click();
199
+ await elementUpdated(el);
200
+ expect(el.value).to.be.undefined;
201
+ expect(changeSpy.callCount).to.equal(1);
202
+ });
203
+ it('prevents [tabindex=0] while `focusin`', async () => {
204
+ const el = await fixture(manageTabIndex());
205
+ const selected = el.querySelector('[value="Section 1"]');
206
+ const toBeSelected = el.querySelector('[value="Section 0"]');
207
+ await elementUpdated(el);
208
+ await waitUntil(() => el.value === 'Section 1', 'wait for selection');
209
+ expect(el.value).to.equal('Section 1');
210
+ expect(selected.tabIndex, 'initially 0').to.equal(0);
211
+ expect(toBeSelected.tabIndex, 'initially -1').to.equal(-1);
212
+ el.focus();
213
+ await elementUpdated(el);
214
+ expect(el.value).to.equal('Section 1');
215
+ expect(selected.tabIndex, '-1 when focusin').to.equal(-1);
216
+ el.blur();
217
+ await elementUpdated(el);
218
+ expect(el.value).to.equal('Section 1');
219
+ expect(selected.tabIndex, '0 when blur').to.equal(0);
220
+ const bindingRect = toBeSelected.getBoundingClientRect();
221
+ await sendMouse({
222
+ steps: [
223
+ {
224
+ type: 'click',
225
+ position: [
226
+ bindingRect.x + bindingRect.width / 2,
227
+ bindingRect.y + bindingRect.height / 2,
228
+ ],
229
+ },
230
+ ],
231
+ });
232
+ await elementUpdated(el);
233
+ expect(el.value).to.equal('Section 0');
234
+ expect(toBeSelected.tabIndex, 'will be new focusable child').to.equal(-1);
235
+ expect(selected.tabIndex, 'no longer selected').to.equal(-1);
236
+ });
237
+ it('manage tab index', async () => {
238
+ const el = await fixture(manageTabIndex());
239
+ await elementUpdated(el);
240
+ expect(el.value).to.equal('Section 1');
241
+ el.focus();
242
+ el.dispatchEvent(arrowUpEvent());
243
+ let focused = document.activeElement;
244
+ focused.click();
245
+ await elementUpdated(el);
246
+ expect(el.value).to.equal('Section 0');
247
+ el.focus();
248
+ el.dispatchEvent(arrowDownEvent());
249
+ el.dispatchEvent(arrowDownEvent());
250
+ focused = document.activeElement;
251
+ expect(focused.expanded, 'not expanded').to.be.false;
252
+ focused.click();
253
+ await elementUpdated(el);
254
+ expect(focused.expanded, 'expanded').to.be.true;
255
+ el.dispatchEvent(arrowDownEvent());
256
+ await elementUpdated(el);
257
+ focused = document.activeElement;
258
+ focused.click();
259
+ await elementUpdated(el);
260
+ expect(el.value).to.equal('Section 3a');
261
+ document.body.focus();
262
+ el.focus();
263
+ focused = document.activeElement;
264
+ expect(focused.selected, 'selected').to.be.true;
265
+ el.dispatchEvent(shiftTabEvent());
266
+ const outsideFocused = document.activeElement;
267
+ expect(typeof outsideFocused).not.to.equal(SideNavItem);
268
+ });
269
+ it('focuses the child anchor not the root when [tabindex=-1]', async () => {
270
+ const el = await fixture(manageTabIndex());
271
+ await elementUpdated(el);
272
+ const firstItem = el.querySelector('[value="Section 0"]');
273
+ const selected = el.querySelector('[selected]');
274
+ expect(selected.tabIndex).to.equal(0);
275
+ expect(firstItem.tabIndex).to.equal(-1);
276
+ const firstRect = firstItem.getBoundingClientRect();
277
+ await sendMouse({
278
+ steps: [
279
+ {
280
+ type: 'move',
281
+ position: [firstRect.x + 2, firstRect.y + 2],
282
+ },
283
+ {
284
+ type: 'down',
285
+ },
286
+ ],
287
+ });
288
+ await elementUpdated(el);
289
+ expect(firstItem.focusElement.matches(':focus')).to.be.true;
290
+ });
291
+ it('manage tab index through shadow DOM', async () => {
292
+ class SideNavTestEl extends LitElement {
293
+ render() {
294
+ return manageTabIndex();
295
+ }
296
+ }
297
+ customElements.define('sidenav-test-el', SideNavTestEl);
298
+ const el = await fixture(html `
299
+ <sidenav-test-el></sidenav-test-el>
300
+ `);
301
+ await elementUpdated(el);
302
+ const rootNode = el.shadowRoot;
303
+ const sidenavEl = rootNode.querySelector('sp-sidenav');
304
+ await elementUpdated(sidenavEl);
305
+ expect(sidenavEl.value).to.equal('Section 1');
306
+ sidenavEl.focus();
307
+ sidenavEl.dispatchEvent(arrowUpEvent());
308
+ let focused = rootNode.activeElement;
309
+ focused.focusElement.click();
310
+ await elementUpdated(sidenavEl);
311
+ expect(sidenavEl.value).to.equal('Section 0');
312
+ sidenavEl.focus();
313
+ sidenavEl.dispatchEvent(arrowDownEvent());
314
+ sidenavEl.dispatchEvent(arrowDownEvent());
315
+ focused = rootNode.activeElement;
316
+ expect(focused.expanded).to.be.false;
317
+ focused.focusElement.click();
318
+ await elementUpdated(sidenavEl);
319
+ expect(focused.expanded).to.be.true;
320
+ sidenavEl.dispatchEvent(arrowDownEvent());
321
+ await elementUpdated(sidenavEl);
322
+ focused = rootNode.activeElement;
323
+ focused.focusElement.click();
324
+ await elementUpdated(sidenavEl);
325
+ expect(sidenavEl.value).to.equal('Section 3a');
326
+ document.body.focus();
327
+ sidenavEl.focus();
328
+ focused = rootNode.activeElement;
329
+ expect(focused.selected).to.be.true;
330
+ sidenavEl.dispatchEvent(shiftTabEvent());
331
+ const outsideFocused = rootNode.activeElement;
332
+ expect(typeof outsideFocused).not.to.equal(SideNavItem);
333
+ });
334
+ it('manage tab index for late added items', async () => {
335
+ const el = await fixture(html `
336
+ <sp-sidenav manage-tab-index>
337
+ <sp-sidenav-item
338
+ value="Section 0"
339
+ label="Section 0"
340
+ ></sp-sidenav-item>
341
+ <sp-sidenav-item
342
+ value="Section 1"
343
+ label="Section 1"
344
+ ></sp-sidenav-item>
345
+ </sp-sidenav>
346
+ `);
347
+ await elementUpdated(el);
348
+ expect(el.manageTabIndex).to.be.true;
349
+ const item1 = el.querySelector('sp-sidenav-item');
350
+ const item2 = el.querySelector('sp-sidenav-item:nth-child(2)');
351
+ await elementUpdated(item1);
352
+ await elementUpdated(item2);
353
+ expect(item1.tabIndex, 'first item tabindex').to.equal(0);
354
+ expect(item2.tabIndex, 'second item tabindex').to.equal(-1);
355
+ const item3 = document.createElement('sp-sidenav-item');
356
+ item3.value = 'Section 2';
357
+ item3.label = 'Section 2';
358
+ await elementUpdated(el);
359
+ el.appendChild(item3);
360
+ await elementUpdated(item3);
361
+ await elementUpdated(el);
362
+ await waitUntil(() => item3.tabIndex === -1, 'after');
363
+ });
364
+ });
365
+ //# sourceMappingURL=sidenav.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidenav.test.js","sourceRoot":"","sources":["sidenav.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport '../sp-sidenav.js';\nimport '../sp-sidenav-item.js';\nimport '../sp-sidenav-heading.js';\nimport { SideNav, SideNavItem } from '../';\nimport { manageTabIndex } from '../stories/sidenav.stories.js';\nimport {\n arrowDownEvent,\n arrowUpEvent,\n shiftTabEvent,\n} from '../../../test/testing-helpers.js';\nimport {\n elementUpdated,\n expect,\n fixture,\n html,\n waitUntil,\n} from '@open-wc/testing';\nimport { LitElement, TemplateResult } from '@spectrum-web-components/base';\nimport { spy } from 'sinon';\nimport { sendMouse } from '../../../test/plugins/browser.js';\n\ndescribe('Sidenav', () => {\n it('loads', async () => {\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav>\n <sp-sidenav-heading label=\"CATEGORY 1\">\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2\"\n label=\"Section 2\"\n ></sp-sidenav-item>\n </sp-sidenav-heading>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n await expect(el).to.be.accessible();\n });\n it('does not accept focus/click/blur when empty', async () => {\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav></sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n\n el.focus();\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n\n el.blur();\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n\n el.click();\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n });\n it('does not accept keyboard events when items are not present', async () => {\n const errorSpy = spy();\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav>\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n const item = el.querySelector('sp-sidenav-item') as SideNavItem;\n window.addEventListener('error', () => errorSpy());\n\n el.dispatchEvent(new FocusEvent('focusin'));\n item.remove();\n\n await elementUpdated(el);\n el.dispatchEvent(\n new KeyboardEvent('keydown', {\n code: 'ArrowDown',\n })\n );\n\n expect(errorSpy.callCount).to.equal(0);\n });\n it('does not accept focus when all children [disabled]', async () => {\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav>\n <sp-sidenav-item\n disabled\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n disabled\n value=\"Section 2\"\n label=\"Section 2\"\n ></sp-sidenav-item>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n\n el.focus();\n await elementUpdated(el);\n\n expect(document.activeElement === el).to.be.false;\n expect(el.matches(':focus-within')).to.be.false;\n });\n it('sets manageTabIndex on new children', async () => {\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav>\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2\"\n label=\"Section 2\"\n ></sp-sidenav-item>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n expect(el.manageTabIndex).to.be.false;\n\n const item1 = el.querySelector('sp-sidenav-item') as SideNavItem;\n expect(item1.tabIndex).to.equal(0);\n\n const newItem = document.createElement('sp-sidenav-item');\n newItem.value = 'Section 3';\n newItem.label = 'Section 3';\n el.appendChild(newItem);\n\n await elementUpdated(newItem);\n\n expect(newItem.tabIndex).to.equal(0);\n\n el.focus();\n const focused = document.activeElement as SideNavItem;\n focused.click();\n expect(focused.selected).to.be.true;\n\n el.dispatchEvent(shiftTabEvent());\n const outsideFocused = document.activeElement as HTMLElement;\n\n expect(typeof outsideFocused).not.to.equal(SideNavItem);\n });\n it('handles select', async () => {\n const changeSpy = spy();\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav @change=${() => changeSpy()}>\n <sp-sidenav-heading label=\"CATEGORY 1\">\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item value=\"Section 2\" label=\"Section 2\">\n <sp-sidenav-item\n value=\"Section 2a\"\n label=\"Section 2a\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n </sp-sidenav-heading>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n expect(el.value).to.be.undefined;\n\n const sidenavItem = el.querySelector(\n '[value=\"Section 2\"]'\n ) as SideNavItem;\n sidenavItem.dispatchEvent(\n new CustomEvent('sidenav-select', {\n bubbles: true,\n detail: {\n value: 'Section 2',\n },\n })\n );\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 2');\n expect(changeSpy.callCount).to.equal(1);\n\n sidenavItem.click();\n\n await elementUpdated(sidenavItem);\n\n const sidenavItemChild = el.querySelector(\n '[value=\"Section 2a\"]'\n ) as SideNavItem;\n sidenavItemChild.click();\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 2a');\n expect(changeSpy.callCount).to.equal(2);\n });\n it('prevents selection', async () => {\n const changeSpy = spy();\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav\n @change=${(event: Event) => {\n event.preventDefault();\n changeSpy();\n }}\n >\n <sp-sidenav-heading label=\"CATEGORY 1\">\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 2\"\n label=\"Section 2\"\n opened\n >\n <sp-sidenav-item\n value=\"Section 2a\"\n label=\"Section 2a\"\n ></sp-sidenav-item>\n </sp-sidenav-item>\n </sp-sidenav-heading>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n\n expect(el.value).to.be.undefined;\n\n el.click();\n\n await elementUpdated(el);\n\n expect(el.value).to.be.undefined;\n expect(changeSpy.callCount).to.equal(1);\n });\n it('prevents [tabindex=0] while `focusin`', async () => {\n const el = await fixture<SideNav>(manageTabIndex());\n const selected = el.querySelector('[value=\"Section 1\"]') as SideNavItem;\n const toBeSelected = el.querySelector(\n '[value=\"Section 0\"]'\n ) as SideNavItem;\n\n await elementUpdated(el);\n await waitUntil(() => el.value === 'Section 1', 'wait for selection');\n\n expect(el.value).to.equal('Section 1');\n expect(selected.tabIndex, 'initially 0').to.equal(0);\n expect(toBeSelected.tabIndex, 'initially -1').to.equal(-1);\n\n el.focus();\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 1');\n expect(selected.tabIndex, '-1 when focusin').to.equal(-1);\n\n el.blur();\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 1');\n expect(selected.tabIndex, '0 when blur').to.equal(0);\n\n const bindingRect = toBeSelected.getBoundingClientRect();\n await sendMouse({\n steps: [\n {\n type: 'click',\n position: [\n bindingRect.x + bindingRect.width / 2,\n bindingRect.y + bindingRect.height / 2,\n ],\n },\n ],\n });\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 0');\n expect(toBeSelected.tabIndex, 'will be new focusable child').to.equal(\n -1\n );\n expect(selected.tabIndex, 'no longer selected').to.equal(-1);\n });\n it('manage tab index', async () => {\n const el = await fixture<SideNav>(manageTabIndex());\n\n await elementUpdated(el);\n expect(el.value).to.equal('Section 1');\n\n el.focus();\n el.dispatchEvent(arrowUpEvent());\n let focused = document.activeElement as SideNavItem;\n focused.click();\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 0');\n\n el.focus();\n el.dispatchEvent(arrowDownEvent());\n el.dispatchEvent(arrowDownEvent());\n focused = document.activeElement as SideNavItem;\n expect(focused.expanded, 'not expanded').to.be.false;\n focused.click();\n\n await elementUpdated(el);\n\n expect(focused.expanded, 'expanded').to.be.true;\n\n el.dispatchEvent(arrowDownEvent());\n await elementUpdated(el);\n focused = document.activeElement as SideNavItem;\n focused.click();\n\n await elementUpdated(el);\n\n expect(el.value).to.equal('Section 3a');\n\n document.body.focus();\n\n el.focus();\n focused = document.activeElement as SideNavItem;\n expect(focused.selected, 'selected').to.be.true;\n\n el.dispatchEvent(shiftTabEvent());\n const outsideFocused = document.activeElement as HTMLElement;\n\n expect(typeof outsideFocused).not.to.equal(SideNavItem);\n });\n it('focuses the child anchor not the root when [tabindex=-1]', async () => {\n const el = await fixture<SideNav>(manageTabIndex());\n\n await elementUpdated(el);\n const firstItem = el.querySelector(\n '[value=\"Section 0\"]'\n ) as SideNavItem;\n const selected = el.querySelector('[selected]') as SideNavItem;\n expect(selected.tabIndex).to.equal(0);\n expect(firstItem.tabIndex).to.equal(-1);\n\n const firstRect = firstItem.getBoundingClientRect();\n await sendMouse({\n steps: [\n {\n type: 'move',\n position: [firstRect.x + 2, firstRect.y + 2],\n },\n {\n type: 'down',\n },\n ],\n });\n await elementUpdated(el);\n\n expect(firstItem.focusElement.matches(':focus')).to.be.true;\n });\n it('manage tab index through shadow DOM', async () => {\n class SideNavTestEl extends LitElement {\n protected render(): TemplateResult {\n return manageTabIndex();\n }\n }\n customElements.define('sidenav-test-el', SideNavTestEl);\n const el = await fixture<SideNav>(html`\n <sidenav-test-el></sidenav-test-el>\n `);\n\n await elementUpdated(el);\n const rootNode = el.shadowRoot as ShadowRoot;\n const sidenavEl = rootNode.querySelector('sp-sidenav') as SideNav;\n\n await elementUpdated(sidenavEl);\n expect(sidenavEl.value).to.equal('Section 1');\n\n sidenavEl.focus();\n sidenavEl.dispatchEvent(arrowUpEvent());\n let focused = rootNode.activeElement as SideNavItem;\n focused.focusElement.click();\n\n await elementUpdated(sidenavEl);\n\n expect(sidenavEl.value).to.equal('Section 0');\n\n sidenavEl.focus();\n sidenavEl.dispatchEvent(arrowDownEvent());\n sidenavEl.dispatchEvent(arrowDownEvent());\n focused = rootNode.activeElement as SideNavItem;\n expect(focused.expanded).to.be.false;\n focused.focusElement.click();\n\n await elementUpdated(sidenavEl);\n\n expect(focused.expanded).to.be.true;\n\n sidenavEl.dispatchEvent(arrowDownEvent());\n await elementUpdated(sidenavEl);\n focused = rootNode.activeElement as SideNavItem;\n focused.focusElement.click();\n\n await elementUpdated(sidenavEl);\n\n expect(sidenavEl.value).to.equal('Section 3a');\n\n document.body.focus();\n\n sidenavEl.focus();\n focused = rootNode.activeElement as SideNavItem;\n expect(focused.selected).to.be.true;\n\n sidenavEl.dispatchEvent(shiftTabEvent());\n const outsideFocused = rootNode.activeElement as HTMLElement;\n\n expect(typeof outsideFocused).not.to.equal(SideNavItem);\n });\n it('manage tab index for late added items', async () => {\n const el = await fixture<SideNav>(\n html`\n <sp-sidenav manage-tab-index>\n <sp-sidenav-item\n value=\"Section 0\"\n label=\"Section 0\"\n ></sp-sidenav-item>\n <sp-sidenav-item\n value=\"Section 1\"\n label=\"Section 1\"\n ></sp-sidenav-item>\n </sp-sidenav>\n `\n );\n\n await elementUpdated(el);\n expect(el.manageTabIndex).to.be.true;\n\n const item1 = el.querySelector('sp-sidenav-item') as SideNavItem;\n const item2 = el.querySelector(\n 'sp-sidenav-item:nth-child(2)'\n ) as SideNavItem;\n\n await elementUpdated(item1);\n await elementUpdated(item2);\n expect(item1.tabIndex, 'first item tabindex').to.equal(0);\n expect(item2.tabIndex, 'second item tabindex').to.equal(-1);\n\n const item3 = document.createElement('sp-sidenav-item');\n item3.value = 'Section 2';\n item3.label = 'Section 2';\n\n await elementUpdated(el);\n\n el.appendChild(item3);\n\n await elementUpdated(item3);\n await elementUpdated(el);\n\n await waitUntil(() => item3.tabIndex === -1, 'after');\n });\n});\n"]}