@spectrum-web-components/tabs 0.9.0 → 0.9.2

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 (74) hide show
  1. package/README.md +154 -36
  2. package/custom-elements.json +41 -13
  3. package/package.json +4 -3
  4. package/sp-tab-panel.dev.js +1 -0
  5. package/sp-tab-panel.dev.js.map +1 -1
  6. package/sp-tab-panel.js +1 -1
  7. package/sp-tab-panel.js.map +2 -2
  8. package/sp-tab.dev.js +1 -0
  9. package/sp-tab.dev.js.map +1 -1
  10. package/sp-tab.js +1 -1
  11. package/sp-tab.js.map +2 -2
  12. package/sp-tabs.dev.js +1 -0
  13. package/sp-tabs.dev.js.map +1 -1
  14. package/sp-tabs.js +1 -1
  15. package/sp-tabs.js.map +2 -2
  16. package/src/Tab.dev.js +18 -7
  17. package/src/Tab.dev.js.map +1 -1
  18. package/src/Tab.js +5 -5
  19. package/src/Tab.js.map +2 -2
  20. package/src/TabPanel.dev.js +1 -0
  21. package/src/TabPanel.dev.js.map +1 -1
  22. package/src/TabPanel.js +2 -2
  23. package/src/TabPanel.js.map +2 -2
  24. package/src/Tabs.d.ts +9 -2
  25. package/src/Tabs.dev.js +52 -12
  26. package/src/Tabs.dev.js.map +2 -2
  27. package/src/Tabs.js +4 -4
  28. package/src/Tabs.js.map +3 -3
  29. package/src/index.dev.js +1 -0
  30. package/src/index.dev.js.map +1 -1
  31. package/src/index.js +1 -1
  32. package/src/index.js.map +1 -1
  33. package/src/spectrum-tab.css.dev.js +1 -0
  34. package/src/spectrum-tab.css.dev.js.map +1 -1
  35. package/src/spectrum-tab.css.js +1 -1
  36. package/src/spectrum-tab.css.js.map +2 -2
  37. package/src/spectrum-tabs.css.dev.js +1 -0
  38. package/src/spectrum-tabs.css.dev.js.map +1 -1
  39. package/src/spectrum-tabs.css.js +1 -1
  40. package/src/spectrum-tabs.css.js.map +2 -2
  41. package/src/tab-panel.css.dev.js +1 -0
  42. package/src/tab-panel.css.dev.js.map +1 -1
  43. package/src/tab-panel.css.js +1 -1
  44. package/src/tab-panel.css.js.map +2 -2
  45. package/src/tab.css.dev.js +1 -0
  46. package/src/tab.css.dev.js.map +1 -1
  47. package/src/tab.css.js +1 -1
  48. package/src/tab.css.js.map +2 -2
  49. package/src/tabs.css.dev.js +2 -1
  50. package/src/tabs.css.dev.js.map +2 -2
  51. package/src/tabs.css.js +2 -2
  52. package/src/tabs.css.js.map +3 -3
  53. package/stories/tabs-horizontal-sizes.stories.js +77 -7
  54. package/stories/tabs-horizontal-sizes.stories.js.map +1 -1
  55. package/stories/tabs-vertical-right-sizes.stories.js +74 -7
  56. package/stories/tabs-vertical-right-sizes.stories.js.map +1 -1
  57. package/stories/tabs-vertical-sizes.stories.js +74 -7
  58. package/stories/tabs-vertical-sizes.stories.js.map +1 -1
  59. package/stories/tabs.stories.js +279 -75
  60. package/stories/tabs.stories.js.map +2 -2
  61. package/test/benchmark/basic-test.js +6 -1
  62. package/test/benchmark/basic-test.js.map +1 -1
  63. package/test/tab.test.js +37 -4
  64. package/test/tab.test.js.map +1 -1
  65. package/test/tabs-horizontal-sizes.test-vrt.js +4 -1
  66. package/test/tabs-horizontal-sizes.test-vrt.js.map +1 -1
  67. package/test/tabs-vertical-right-sizes.test-vrt.js +4 -1
  68. package/test/tabs-vertical-right-sizes.test-vrt.js.map +1 -1
  69. package/test/tabs-vertical-sizes.test-vrt.js +4 -1
  70. package/test/tabs-vertical-sizes.test-vrt.js.map +1 -1
  71. package/test/tabs.test-vrt.js +4 -1
  72. package/test/tabs.test-vrt.js.map +1 -1
  73. package/test/tabs.test.js +428 -17
  74. package/test/tabs.test.js.map +1 -1
package/test/tabs.test.js CHANGED
@@ -1,4 +1,30 @@
1
- import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components/tabs/sp-tab.js";import"@spectrum-web-components/tabs/sp-tab-panel.js";import{Tab as u}from"@spectrum-web-components/tabs";import"@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark.js";import{elementUpdated as s,expect as t,fixture as b,oneEvent as y,waitUntil as E}from"@open-wc/testing";import{html as o}from"lit/static-html.js";import{LitElement as S}from"@spectrum-web-components/base";import{arrowDownEvent as g,arrowLeftEvent as f,arrowRightEvent as m,arrowUpEvent as w,enterEvent as v,spaceEvent as T}from"../../../test/testing-helpers.js";import{sendKeys as h}from"@web/test-runner-commands";const d=async()=>{const e=await b(o`
1
+ "use strict";
2
+ import "@spectrum-web-components/tabs/sp-tabs.js";
3
+ import "@spectrum-web-components/tabs/sp-tab.js";
4
+ import "@spectrum-web-components/tabs/sp-tab-panel.js";
5
+ import { Tab } from "@spectrum-web-components/tabs";
6
+ import "@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark.js";
7
+ import {
8
+ elementUpdated,
9
+ expect,
10
+ fixture,
11
+ oneEvent,
12
+ waitUntil
13
+ } from "@open-wc/testing";
14
+ import { html } from "lit/static-html.js";
15
+ import { LitElement } from "@spectrum-web-components/base";
16
+ import {
17
+ arrowDownEvent,
18
+ arrowLeftEvent,
19
+ arrowRightEvent,
20
+ arrowUpEvent,
21
+ enterEvent,
22
+ spaceEvent
23
+ } from "../../../test/testing-helpers.js";
24
+ import { sendKeys } from "@web/test-runner-commands";
25
+ const createTabs = async () => {
26
+ const tabs = await fixture(
27
+ html`
2
28
  <sp-tabs selected="first">
3
29
  <sp-tab label="Tab 1" value="first"></sp-tab>
4
30
  <sp-tab label="Tab 2" value="second"></sp-tab>
@@ -7,47 +33,270 @@ import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components
7
33
  <sp-tab-panel value="second">Second tab content</sp-tab-panel>
8
34
  <sp-tab-panel value="third">Third tab content</sp-tab-panel>
9
35
  </sp-tabs>
10
- `);return await s(e),e};describe("Tabs",()=>{it("loads accessibly",async()=>{const e=await d(),a=e.querySelectorAll("sp-tab");t(a).to.exist,t(a.length).to.equal(3),await t(e).to.be.accessible()}),it("loads accessibly w/o panels",async()=>{const e=await b(o`
36
+ `
37
+ );
38
+ await elementUpdated(tabs);
39
+ return tabs;
40
+ };
41
+ describe("Tabs", () => {
42
+ it("loads accessibly", async () => {
43
+ const tabs = await createTabs();
44
+ const tabList = tabs.querySelectorAll("sp-tab");
45
+ expect(tabList).to.exist;
46
+ expect(tabList.length).to.equal(3);
47
+ await expect(tabs).to.be.accessible();
48
+ });
49
+ it("loads accessibly w/o panels", async () => {
50
+ const tabs = await fixture(
51
+ html`
11
52
  <sp-tabs selected="first">
12
53
  <sp-tab value="first">Tab 1</sp-tab>
13
54
  <sp-tab value="second">Tab 2</sp-tab>
14
55
  <sp-tab value="third">Tab 3</sp-tab>
15
56
  </sp-tabs>
16
- `),a=e.querySelectorAll("sp-tab");t(a).to.exist,t(a.length).to.equal(3),await t(e).to.be.accessible()}),it("can be disabled",async()=>{const e=await d(),a=e.querySelector('[label="Tab 3"]');e.disabled=!0,await s(e),t(e.selected).to.equal("first"),a.click(),await s(e),t(e.selected).to.equal("first")}),it("can have disabled sp-tab children",async()=>{const e=await d(),a=e.querySelector('[label="Tab 2"]'),c=e.querySelector('[label="Tab 3"]');c.disabled=!0,await s(c),t(e.selected).to.equal("first"),c.click(),await s(e),t(e.selected).to.equal("first"),a.click(),await s(e),t(e.selected).to.equal("second")}),it("reflects selected tab with selected property",async()=>{const e=await d(),a=e.querySelector("sp-tab[value=first]"),c=e.querySelector("sp-tab[value=second]"),l=e.querySelector("sp-tab[value=third]"),n=e.querySelector("sp-tab-panel[value=first]"),i=e.querySelector("sp-tab-panel[value=second]"),r=e.querySelector("sp-tab-panel[value=third]");t(a.selected,"first: 1, selected").to.be.true,t(n.selected,"first panel: 1, selected").to.be.true,t(c.selected,"second: 1, not selected").to.be.false,t(i.selected,"second panel: 1, not selected").to.be.false,t(l.selected,"third: 1, not selected").to.be.false,t(r.selected,"third panel: 1, not selected").to.be.false,t(e.selected).to.equal(a.value),c.click(),await s(e),t(a.selected,"first: 2, not selected").to.be.false,t(n.selected,"first panel: 2, not selected").to.be.false,t(c.selected,"second: 2, selected").to.be.true,t(c.selected,"first panel: 2, selected").to.be.true,t(l.selected,"third: 2, not selected").to.be.false,t(l.selected,"first panel: 2, not selected").to.be.false,t(e.selected).to.equal(c.value),l.click(),await s(e),t(a.selected,"first: 3, not selected").to.be.false,t(n.selected,"first panel: 3, not selected").to.be.false,t(c.selected,"second: 3, not selected").to.be.false,t(i.selected,"second panel: 3, not selected").to.be.false,t(l.selected,"third: 3, selected").to.be.true,t(l.selected,"first panel: 3, selected").to.be.true,t(e.selected).to.equal(l.value)}),it("autofocuses",async()=>{const e=await b(o`
57
+ `
58
+ );
59
+ const tabList = tabs.querySelectorAll("sp-tab");
60
+ expect(tabList).to.exist;
61
+ expect(tabList.length).to.equal(3);
62
+ await expect(tabs).to.be.accessible();
63
+ });
64
+ it("can be disabled", async () => {
65
+ const tabs = await createTabs();
66
+ const tab = tabs.querySelector('[label="Tab 3"]');
67
+ tabs.disabled = true;
68
+ await elementUpdated(tabs);
69
+ expect(tabs.selected).to.equal("first");
70
+ tab.click();
71
+ await elementUpdated(tabs);
72
+ expect(tabs.selected).to.equal("first");
73
+ });
74
+ it("can have disabled sp-tab children", async () => {
75
+ const tabs = await createTabs();
76
+ const tab2 = tabs.querySelector('[label="Tab 2"]');
77
+ const tab3 = tabs.querySelector('[label="Tab 3"]');
78
+ tab3.disabled = true;
79
+ await elementUpdated(tab3);
80
+ expect(tabs.selected).to.equal("first");
81
+ tab3.click();
82
+ await elementUpdated(tabs);
83
+ expect(tabs.selected).to.equal("first");
84
+ tab2.click();
85
+ await elementUpdated(tabs);
86
+ expect(tabs.selected).to.equal("second");
87
+ });
88
+ it("reflects selected tab with selected property", async () => {
89
+ const tabs = await createTabs();
90
+ const firstTab = tabs.querySelector("sp-tab[value=first]");
91
+ const secondTab = tabs.querySelector("sp-tab[value=second]");
92
+ const thirdTab = tabs.querySelector("sp-tab[value=third]");
93
+ const firstPanel = tabs.querySelector(
94
+ "sp-tab-panel[value=first]"
95
+ );
96
+ const secondPanel = tabs.querySelector(
97
+ "sp-tab-panel[value=second]"
98
+ );
99
+ const thirdPanel = tabs.querySelector(
100
+ "sp-tab-panel[value=third]"
101
+ );
102
+ expect(firstTab.selected, "first: 1, selected").to.be.true;
103
+ expect(firstPanel.selected, "first panel: 1, selected").to.be.true;
104
+ expect(secondTab.selected, "second: 1, not selected").to.be.false;
105
+ expect(secondPanel.selected, "second panel: 1, not selected").to.be.false;
106
+ expect(thirdTab.selected, "third: 1, not selected").to.be.false;
107
+ expect(thirdPanel.selected, "third panel: 1, not selected").to.be.false;
108
+ expect(tabs.selected).to.equal(firstTab.value);
109
+ secondTab.click();
110
+ await elementUpdated(tabs);
111
+ expect(firstTab.selected, "first: 2, not selected").to.be.false;
112
+ expect(firstPanel.selected, "first panel: 2, not selected").to.be.false;
113
+ expect(secondTab.selected, "second: 2, selected").to.be.true;
114
+ expect(secondTab.selected, "first panel: 2, selected").to.be.true;
115
+ expect(thirdTab.selected, "third: 2, not selected").to.be.false;
116
+ expect(thirdTab.selected, "first panel: 2, not selected").to.be.false;
117
+ expect(tabs.selected).to.equal(secondTab.value);
118
+ thirdTab.click();
119
+ await elementUpdated(tabs);
120
+ expect(firstTab.selected, "first: 3, not selected").to.be.false;
121
+ expect(firstPanel.selected, "first panel: 3, not selected").to.be.false;
122
+ expect(secondTab.selected, "second: 3, not selected").to.be.false;
123
+ expect(secondPanel.selected, "second panel: 3, not selected").to.be.false;
124
+ expect(thirdTab.selected, "third: 3, selected").to.be.true;
125
+ expect(thirdTab.selected, "first panel: 3, selected").to.be.true;
126
+ expect(tabs.selected).to.equal(thirdTab.value);
127
+ });
128
+ it("autofocuses", async () => {
129
+ const tabs = await fixture(
130
+ html`
17
131
  <sp-tabs selected="second" autofocus>
18
132
  <sp-tab label="Tab 1" value="first"></sp-tab>
19
133
  <sp-tab label="Tab 2" value="second"></sp-tab>
20
134
  <sp-tab label="Tab 3" value="third"></sp-tab>
21
135
  </sp-tabs>
22
- `);await s(e);const a=e.querySelector('[label="Tab 2"]');await E(()=>document.activeElement===a,"Autofocused")}),it("auto",async()=>{const e=await b(o`
136
+ `
137
+ );
138
+ await elementUpdated(tabs);
139
+ const autoElement = tabs.querySelector('[label="Tab 2"]');
140
+ await waitUntil(
141
+ () => document.activeElement === autoElement,
142
+ "Autofocused"
143
+ );
144
+ });
145
+ it("auto", async () => {
146
+ const el = await fixture(
147
+ html`
23
148
  <sp-tabs selected="second" auto>
24
149
  <sp-tab label="Tab 1" value="first"></sp-tab>
25
150
  <sp-tab label="Tab 2" value="second"></sp-tab>
26
151
  <sp-tab label="Tab 3" value="third"></sp-tab>
27
152
  </sp-tabs>
28
- `);await s(e),t(e.selected).to.equal("second"),e.focus(),await h({press:"ArrowLeft"}),t(e.selected).to.equal("first"),await h({press:"ArrowLeft"}),t(e.selected).to.equal("third"),await h({press:"ArrowRight"}),t(e.selected).to.equal("first")}),it("forces only one tab to be selected",async()=>{const e=await d(),a=e.querySelectorAll("sp-tab[selected]");t(e.selected).to.equal("first"),t(a.length).to.equal(1)}),it("de-selects all but first selected tab if multiple selected",async()=>{const e=await d(),a=e.querySelector("sp-tab[value=first]"),c=e.querySelector("sp-tab[value=second]");if(!(a instanceof u))throw new Error("tab1 not of type Tab");if(!(c instanceof u))throw new Error("tab2 not of type Tab");t(e.selected).to.equal("first"),t(a.selected).to.be.true,t(c.selected).to.be.false}),it("ensures setting selection updates selected tab",async()=>{const e=await d(),a=e.querySelector("sp-tab[value=first]"),c=e.querySelector("sp-tab[value=second]"),l=e.querySelector("sp-tab[value=third]");if(!(a instanceof u))throw new Error("tab1 not of type Tab");if(!(c instanceof u))throw new Error("tab2 not of type Tab");if(!(l instanceof u))throw new Error("tab3 not of type Tab");t(e.selected).to.equal("first"),t(a.selected,"first: 1, selected").to.be.true,t(c.selected,"second: 1, not selected").to.be.false,t(l.selected,"thurd: 1, not selected").to.be.false,e.selected="second",await s(e),t(e.selected).to.equal("second"),t(a.selected,"first: 2, not selected").to.be.false,t(c.selected,"second: 2, selected").to.be.true,t(l.selected,"third: 2, not selected").to.be.false,e.selected="third",await s(e),t(e.selected).to.equal("third"),t(a.selected,"first: 3, not selected").to.be.false,t(c.selected,"second: 3, not selected").to.be.false,t(l.selected,"third: 3, selected").to.be.true}),it("ensures setting selected and clicking on tab both work together",async()=>{const e=await d(),a=e.querySelector("sp-tab[value=first]"),c=e.querySelector("sp-tab[value=second]"),l=e.querySelector("sp-tab[value=third]");if(!(a instanceof u))throw new Error("tab1 not of type Tab");if(!(c instanceof u))throw new Error("tab2 not of type Tab");if(!(l instanceof u))throw new Error("tab3 not of type Tab");c.click(),await s(e),t(e.selected).to.equal("second"),t(a.selected).to.be.false,t(c.selected).to.be.true,t(l.selected).to.be.false,e.selected="first",await s(e),t(e.selected).to.equal("first"),t(a.selected).to.be.true,t(c.selected).to.be.false,t(l.selected).to.be.false}),it("displays `vertical`",async()=>{const e=await b(o`
153
+ `
154
+ );
155
+ await elementUpdated(el);
156
+ expect(el.selected).to.equal("second");
157
+ el.focus();
158
+ await sendKeys({
159
+ press: "ArrowLeft"
160
+ });
161
+ expect(el.selected).to.equal("first");
162
+ await sendKeys({
163
+ press: "ArrowLeft"
164
+ });
165
+ expect(el.selected).to.equal("third");
166
+ await sendKeys({
167
+ press: "ArrowRight"
168
+ });
169
+ expect(el.selected).to.equal("first");
170
+ });
171
+ it("forces only one tab to be selected", async () => {
172
+ const tabs = await createTabs();
173
+ const selectedTabs = tabs.querySelectorAll("sp-tab[selected]");
174
+ expect(tabs.selected).to.equal("first");
175
+ expect(selectedTabs.length).to.equal(1);
176
+ });
177
+ it("de-selects all but first selected tab if multiple selected", async () => {
178
+ const tabs = await createTabs();
179
+ const tab1 = tabs.querySelector("sp-tab[value=first]");
180
+ const tab2 = tabs.querySelector("sp-tab[value=second]");
181
+ if (!(tab1 instanceof Tab))
182
+ throw new Error("tab1 not of type Tab");
183
+ if (!(tab2 instanceof Tab))
184
+ throw new Error("tab2 not of type Tab");
185
+ expect(tabs.selected).to.equal("first");
186
+ expect(tab1.selected).to.be.true;
187
+ expect(tab2.selected).to.be.false;
188
+ });
189
+ it("ensures setting selection updates selected tab", async () => {
190
+ const tabs = await createTabs();
191
+ const tab1 = tabs.querySelector("sp-tab[value=first]");
192
+ const tab2 = tabs.querySelector("sp-tab[value=second]");
193
+ const tab3 = tabs.querySelector("sp-tab[value=third]");
194
+ if (!(tab1 instanceof Tab))
195
+ throw new Error("tab1 not of type Tab");
196
+ if (!(tab2 instanceof Tab))
197
+ throw new Error("tab2 not of type Tab");
198
+ if (!(tab3 instanceof Tab))
199
+ throw new Error("tab3 not of type Tab");
200
+ expect(tabs.selected).to.equal("first");
201
+ expect(tab1.selected, "first: 1, selected").to.be.true;
202
+ expect(tab2.selected, "second: 1, not selected").to.be.false;
203
+ expect(tab3.selected, "thurd: 1, not selected").to.be.false;
204
+ tabs.selected = "second";
205
+ await elementUpdated(tabs);
206
+ expect(tabs.selected).to.equal("second");
207
+ expect(tab1.selected, "first: 2, not selected").to.be.false;
208
+ expect(tab2.selected, "second: 2, selected").to.be.true;
209
+ expect(tab3.selected, "third: 2, not selected").to.be.false;
210
+ tabs.selected = "third";
211
+ await elementUpdated(tabs);
212
+ expect(tabs.selected).to.equal("third");
213
+ expect(tab1.selected, "first: 3, not selected").to.be.false;
214
+ expect(tab2.selected, "second: 3, not selected").to.be.false;
215
+ expect(tab3.selected, "third: 3, selected").to.be.true;
216
+ });
217
+ it("ensures setting selected and clicking on tab both work together", async () => {
218
+ const tabs = await createTabs();
219
+ const tab1 = tabs.querySelector("sp-tab[value=first]");
220
+ const tab2 = tabs.querySelector("sp-tab[value=second]");
221
+ const tab3 = tabs.querySelector("sp-tab[value=third]");
222
+ if (!(tab1 instanceof Tab))
223
+ throw new Error("tab1 not of type Tab");
224
+ if (!(tab2 instanceof Tab))
225
+ throw new Error("tab2 not of type Tab");
226
+ if (!(tab3 instanceof Tab))
227
+ throw new Error("tab3 not of type Tab");
228
+ tab2.click();
229
+ await elementUpdated(tabs);
230
+ expect(tabs.selected).to.equal("second");
231
+ expect(tab1.selected).to.be.false;
232
+ expect(tab2.selected).to.be.true;
233
+ expect(tab3.selected).to.be.false;
234
+ tabs.selected = "first";
235
+ await elementUpdated(tabs);
236
+ expect(tabs.selected).to.equal("first");
237
+ expect(tab1.selected).to.be.true;
238
+ expect(tab2.selected).to.be.false;
239
+ expect(tab3.selected).to.be.false;
240
+ });
241
+ it("displays `vertical`", async () => {
242
+ const el = await fixture(html`
29
243
  <sp-tabs selected="first" direction="vertical">
30
244
  <sp-tab label="Tab 1" value="first"></sp-tab>
31
245
  <sp-tab label="Tab 2" value="second"></sp-tab>
32
246
  <sp-tab label="Tab 3" value="third"></sp-tab>
33
247
  </sp-tabs>
34
- `);await s(e),t(e.selected).to.be.equal("first"),e.selected="first",await s(e),t(e.selected).to.be.equal("first")}),it("displays with nothing `selected`",async()=>{const e=await b(o`
248
+ `);
249
+ await elementUpdated(el);
250
+ expect(el.selected).to.be.equal("first");
251
+ el.selected = "first";
252
+ await elementUpdated(el);
253
+ expect(el.selected).to.be.equal("first");
254
+ });
255
+ it("displays with nothing `selected`", async () => {
256
+ const el = await fixture(html`
35
257
  <sp-tabs>
36
258
  <sp-tab label="Tab 1" value="first"></sp-tab>
37
259
  <sp-tab label="Tab 2" value="second"></sp-tab>
38
260
  <sp-tab label="Tab 3" value="third"></sp-tab>
39
261
  </sp-tabs>
40
- `);await s(e),t(e.selected).to.be.equal(""),e.selected="first",await s(e),t(e.selected).to.be.equal("first")}),it("ignores children with no `value`",async()=>{const e=await b(o`
262
+ `);
263
+ await elementUpdated(el);
264
+ expect(el.selected).to.be.equal("");
265
+ el.selected = "first";
266
+ await elementUpdated(el);
267
+ expect(el.selected).to.be.equal("first");
268
+ });
269
+ it("ignores children with no `value`", async () => {
270
+ const el = await fixture(html`
41
271
  <sp-tabs selected="first">
42
272
  <sp-tab label="Tab 1" value="first"></sp-tab>
43
273
  <div id="other">Other thing</div>
44
274
  </sp-tabs>
45
- `);await s(e),t(e.selected).to.be.equal("first"),e.querySelector("#other").click(),await s(e),t(e.selected).to.be.equal("first")}),it("allows selection to be cancellable",async()=>{const a=await b(o`
46
- <sp-tabs selected="first" @change=${l=>l.preventDefault()}>
275
+ `);
276
+ await elementUpdated(el);
277
+ expect(el.selected).to.be.equal("first");
278
+ const otherThing = el.querySelector("#other");
279
+ otherThing.click();
280
+ await elementUpdated(el);
281
+ expect(el.selected).to.be.equal("first");
282
+ });
283
+ it("allows selection to be cancellable", async () => {
284
+ const cancelSelection = (event) => event.preventDefault();
285
+ const el = await fixture(html`
286
+ <sp-tabs selected="first" @change=${cancelSelection}>
47
287
  <sp-tab label="Tab 1" value="first"></sp-tab>
48
288
  <sp-tab label="Tab 2" value="second"></sp-tab>
49
289
  </sp-tabs>
50
- `);await s(a),t(a.selected).to.be.equal("first"),a.querySelector('[value="second"]').click(),await s(a),t(a.selected).to.be.equal("first")}),it("prevents [tabindex=0] while `focusin`",async()=>{const e=await b(o`
290
+ `);
291
+ await elementUpdated(el);
292
+ expect(el.selected).to.be.equal("first");
293
+ const secondTab = el.querySelector('[value="second"]');
294
+ secondTab.click();
295
+ await elementUpdated(el);
296
+ expect(el.selected).to.be.equal("first");
297
+ });
298
+ it("prevents [tabindex=0] while `focusin`", async () => {
299
+ const el = await fixture(html`
51
300
  <sp-tabs>
52
301
  <sp-tab label="Tab 1" value="first" selected>
53
302
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
@@ -56,7 +305,28 @@ import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components
56
305
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
57
306
  </sp-tab>
58
307
  </sp-tabs>
59
- `),a=e.querySelector('[value="first"]'),c=e.querySelector('[value="second"]');await s(e),await E(()=>e.selected==="first","wait for selection"),t(e.selected).to.equal("first"),t(a.tabIndex).to.equal(0),c.dispatchEvent(new Event("focusin",{bubbles:!0})),await s(e),t(e.selected).to.equal("first"),t(a.tabIndex).to.equal(-1),c.dispatchEvent(new Event("focusout",{bubbles:!0})),await s(e),t(e.selected).to.equal("first"),t(a.tabIndex).to.equal(0),c.click(),await s(e),t(e.selected).to.equal("second"),t(c.tabIndex).to.equal(0)}),it("accepts keyboard based selection",async()=>{const e=await b(o`
308
+ `);
309
+ const selected = el.querySelector('[value="first"]');
310
+ const toBeSelected = el.querySelector('[value="second"]');
311
+ await elementUpdated(el);
312
+ await waitUntil(() => el.selected === "first", "wait for selection");
313
+ expect(el.selected).to.equal("first");
314
+ expect(selected.tabIndex).to.equal(0);
315
+ toBeSelected.dispatchEvent(new Event("focusin", { bubbles: true }));
316
+ await elementUpdated(el);
317
+ expect(el.selected).to.equal("first");
318
+ expect(selected.tabIndex).to.equal(-1);
319
+ toBeSelected.dispatchEvent(new Event("focusout", { bubbles: true }));
320
+ await elementUpdated(el);
321
+ expect(el.selected).to.equal("first");
322
+ expect(selected.tabIndex).to.equal(0);
323
+ toBeSelected.click();
324
+ await elementUpdated(el);
325
+ expect(el.selected).to.equal("second");
326
+ expect(toBeSelected.tabIndex).to.equal(0);
327
+ });
328
+ it("accepts keyboard based selection", async () => {
329
+ const el = await fixture(html`
60
330
  <sp-tabs selected="Unknown">
61
331
  <sp-tab label="Tab 1" value="first">
62
332
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
@@ -65,7 +335,33 @@ import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components
65
335
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
66
336
  </sp-tab>
67
337
  </sp-tabs>
68
- `);await s(e),t(e.selected).to.be.equal("");const a=e.querySelector('[value="first"]'),c=e.querySelector('[value="second"]');a.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),a.focus(),await s(e),t(document.activeElement===a,"Focus first tab").to.be.true,a.dispatchEvent(f()),a.dispatchEvent(w()),await s(e),t(document.activeElement===c,"Focus second tab").to.be.true,c.dispatchEvent(v()),await s(e),t(e.selected).to.be.equal("second"),c.dispatchEvent(m()),await s(e),t(document.activeElement===a,"Focus first tab").to.be.true,a.dispatchEvent(T()),await s(e),t(e.selected).to.be.equal("first")}),it("accepts keyboard based selection through shadow DOM",async()=>{class e extends S{render(){return o`
338
+ `);
339
+ await elementUpdated(el);
340
+ expect(el.selected).to.be.equal("");
341
+ const firstTab = el.querySelector('[value="first"]');
342
+ const secondTab = el.querySelector('[value="second"]');
343
+ firstTab.dispatchEvent(new FocusEvent("focusin", { bubbles: true }));
344
+ firstTab.focus();
345
+ await elementUpdated(el);
346
+ expect(document.activeElement === firstTab, "Focus first tab").to.be.true;
347
+ firstTab.dispatchEvent(arrowLeftEvent());
348
+ firstTab.dispatchEvent(arrowUpEvent());
349
+ await elementUpdated(el);
350
+ expect(document.activeElement === secondTab, "Focus second tab").to.be.true;
351
+ secondTab.dispatchEvent(enterEvent());
352
+ await elementUpdated(el);
353
+ expect(el.selected).to.be.equal("second");
354
+ secondTab.dispatchEvent(arrowRightEvent());
355
+ await elementUpdated(el);
356
+ expect(document.activeElement === firstTab, "Focus first tab").to.be.true;
357
+ firstTab.dispatchEvent(spaceEvent());
358
+ await elementUpdated(el);
359
+ expect(el.selected).to.be.equal("first");
360
+ });
361
+ it("accepts keyboard based selection through shadow DOM", async () => {
362
+ class TabTestEl extends LitElement {
363
+ render() {
364
+ return html`
69
365
  <sp-tabs selected="Unknown">
70
366
  <sp-tab label="Tab 1" value="first">
71
367
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
@@ -74,9 +370,45 @@ import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components
74
370
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
75
371
  </sp-tab>
76
372
  </sp-tabs>
77
- `}}customElements.define("tab-test-el",e);const a=await b(o`
373
+ `;
374
+ }
375
+ }
376
+ customElements.define("tab-test-el", TabTestEl);
377
+ const el = await fixture(
378
+ html`
78
379
  <tab-test-el></tab-test-el>
79
- `);await s(a);const c=a.shadowRoot,l=c.querySelector("sp-tabs");await s(l),t(l.selected).to.be.equal("");const n=l.querySelector('[value="first"]'),i=l.querySelector('[value="second"]');n.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),n.focus(),await s(a);let r=c.activeElement;t(r===n,"Focus first tab").to.be.true,n.dispatchEvent(f()),n.dispatchEvent(w()),await s(a),r=c.activeElement,t(r===i,"Focus second tab").to.be.true,i.dispatchEvent(v()),await s(a),t(l.selected).to.be.equal("second"),i.dispatchEvent(m()),await s(a),r=c.activeElement,t(r===n,"Focus first tab").to.be.true,n.dispatchEvent(T()),await s(a),t(l.selected).to.be.equal("first")}),it('accepts keyboard based selection - [direction="vertical"]',async()=>{const e=await b(o`
380
+ `
381
+ );
382
+ await elementUpdated(el);
383
+ const rootNode = el.shadowRoot;
384
+ const tabsEl = rootNode.querySelector("sp-tabs");
385
+ await elementUpdated(tabsEl);
386
+ expect(tabsEl.selected).to.be.equal("");
387
+ const firstTab = tabsEl.querySelector('[value="first"]');
388
+ const secondTab = tabsEl.querySelector('[value="second"]');
389
+ firstTab.dispatchEvent(new FocusEvent("focusin", { bubbles: true }));
390
+ firstTab.focus();
391
+ await elementUpdated(el);
392
+ let activeElement = rootNode.activeElement;
393
+ expect(activeElement === firstTab, "Focus first tab").to.be.true;
394
+ firstTab.dispatchEvent(arrowLeftEvent());
395
+ firstTab.dispatchEvent(arrowUpEvent());
396
+ await elementUpdated(el);
397
+ activeElement = rootNode.activeElement;
398
+ expect(activeElement === secondTab, "Focus second tab").to.be.true;
399
+ secondTab.dispatchEvent(enterEvent());
400
+ await elementUpdated(el);
401
+ expect(tabsEl.selected).to.be.equal("second");
402
+ secondTab.dispatchEvent(arrowRightEvent());
403
+ await elementUpdated(el);
404
+ activeElement = rootNode.activeElement;
405
+ expect(activeElement === firstTab, "Focus first tab").to.be.true;
406
+ firstTab.dispatchEvent(spaceEvent());
407
+ await elementUpdated(el);
408
+ expect(tabsEl.selected).to.be.equal("first");
409
+ });
410
+ it('accepts keyboard based selection - [direction="vertical"]', async () => {
411
+ const el = await fixture(html`
80
412
  <sp-tabs selected="Unknown" direction="vertical">
81
413
  <sp-tab label="Tab 1" value="first">
82
414
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
@@ -85,15 +417,94 @@ import"@spectrum-web-components/tabs/sp-tabs.js";import"@spectrum-web-components
85
417
  <sp-icon-checkmark slot="icon"></sp-icon-checkmark>
86
418
  </sp-tab>
87
419
  </sp-tabs>
88
- `);await s(e),t(e.selected).to.be.equal("");const a=e.querySelector('[value="first"]'),c=e.querySelector('[value="second"]');a.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),a.focus(),await s(e),t(document.activeElement===a,"Focus first tab").to.be.true,a.dispatchEvent(f()),a.dispatchEvent(w()),await s(e),t(document.activeElement===c,"Focus second tab").to.be.true,c.dispatchEvent(v()),await s(e),t(e.selected).to.be.equal("second"),c.dispatchEvent(g()),await s(e),t(document.activeElement===a,"Focus first tab").to.be.true,a.dispatchEvent(T()),await s(e),t(e.selected).to.be.equal("first")}),it("selects through slotted DOM",async()=>{const e=await b(o`
420
+ `);
421
+ await elementUpdated(el);
422
+ expect(el.selected).to.be.equal("");
423
+ const firstTab = el.querySelector('[value="first"]');
424
+ const secondTab = el.querySelector('[value="second"]');
425
+ firstTab.dispatchEvent(new FocusEvent("focusin", { bubbles: true }));
426
+ firstTab.focus();
427
+ await elementUpdated(el);
428
+ expect(document.activeElement === firstTab, "Focus first tab").to.be.true;
429
+ firstTab.dispatchEvent(arrowLeftEvent());
430
+ firstTab.dispatchEvent(arrowUpEvent());
431
+ await elementUpdated(el);
432
+ expect(document.activeElement === secondTab, "Focus second tab").to.be.true;
433
+ secondTab.dispatchEvent(enterEvent());
434
+ await elementUpdated(el);
435
+ expect(el.selected).to.be.equal("second");
436
+ secondTab.dispatchEvent(arrowDownEvent());
437
+ await elementUpdated(el);
438
+ expect(document.activeElement === firstTab, "Focus first tab").to.be.true;
439
+ firstTab.dispatchEvent(spaceEvent());
440
+ await elementUpdated(el);
441
+ expect(el.selected).to.be.equal("first");
442
+ });
443
+ it("selects through slotted DOM", async () => {
444
+ const el = await fixture(
445
+ html`
89
446
  <sp-tabs selected="first">
90
447
  <sp-tab value="first">Tab 1</sp-tab>
91
448
  <sp-tab value="second"><span>Tab 2</span></sp-tab>
92
449
  </sp-tabs>
93
- `),a=e.querySelector("span");await s(e),t(e.selected).to.equal("first"),a.click(),await s(e),t(e.selected).to.equal("second")}),it("updates selection indicator in response to tab updates",async()=>{const e=await b(o`
450
+ `
451
+ );
452
+ const span = el.querySelector("span");
453
+ await elementUpdated(el);
454
+ expect(el.selected).to.equal("first");
455
+ span.click();
456
+ await elementUpdated(el);
457
+ expect(el.selected).to.equal("second");
458
+ });
459
+ it("updates selection indicator in response to tab updates", async () => {
460
+ const el = await fixture(
461
+ html`
94
462
  <sp-tabs selected="first">
95
463
  <sp-tab value="first">Tab 1</sp-tab>
96
464
  <sp-tab value="second">Tab 2</sp-tab>
97
465
  </sp-tabs>
98
- `),a=e.querySelector('[value="first"]');await s(e);const c=/scaleX\((.+)\)/,l=c.exec(e.selectionIndicatorStyle),n=parseFloat(l[1]);let i=y(e,"sp-tab-contentchange");a.textContent="WWWWWWWWWWWWWWWWWWWWWWWWW",await i,await s(e);const r=c.exec(e.selectionIndicatorStyle),p=parseFloat(r[1]);t(n).to.be.lessThan(p),i=y(e,"sp-tab-contentchange"),a.textContent="W",await i,await s(e);const k=c.exec(e.selectionIndicatorStyle),q=parseFloat(k[1]);t(n).to.be.greaterThan(q),t(p).to.be.greaterThan(q)}),it("clicks on #list do not throw",async()=>{const a=(await d()).shadowRoot.querySelector("#list");let c=!1;const l=window.onerror;window.onerror=()=>{c=!0},a.dispatchEvent(new MouseEvent("click")),t(c,"it should not error").to.be.false,window.onerror=l})});
466
+ `
467
+ );
468
+ const selected = el.querySelector('[value="first"]');
469
+ await elementUpdated(el);
470
+ const extractScaleX = /scaleX\((.+)\)/;
471
+ const initialExec = extractScaleX.exec(
472
+ el.selectionIndicatorStyle
473
+ );
474
+ const initialWidth = parseFloat(initialExec[1]);
475
+ let contentchanged = oneEvent(el, "sp-tab-contentchange");
476
+ selected.textContent = "WWWWWWWWWWWWWWWWWWWWWWWWW";
477
+ await contentchanged;
478
+ await elementUpdated(el);
479
+ const longerExec = extractScaleX.exec(
480
+ el.selectionIndicatorStyle
481
+ );
482
+ const longerWidth = parseFloat(longerExec[1]);
483
+ expect(initialWidth).to.be.lessThan(longerWidth);
484
+ contentchanged = oneEvent(el, "sp-tab-contentchange");
485
+ selected.textContent = "W";
486
+ await contentchanged;
487
+ await elementUpdated(el);
488
+ const shorterExec = extractScaleX.exec(
489
+ el.selectionIndicatorStyle
490
+ );
491
+ const shorterWidth = parseFloat(shorterExec[1]);
492
+ expect(initialWidth).to.be.greaterThan(shorterWidth);
493
+ expect(longerWidth).to.be.greaterThan(shorterWidth);
494
+ });
495
+ it("clicks on #list do not throw", async () => {
496
+ const tabs = await createTabs();
497
+ const tabList = tabs.shadowRoot.querySelector(
498
+ "#list"
499
+ );
500
+ let hasError = false;
501
+ const oldOnerror = window.onerror;
502
+ window.onerror = () => {
503
+ hasError = true;
504
+ };
505
+ tabList.dispatchEvent(new MouseEvent("click"));
506
+ expect(hasError, "it should not error").to.be.false;
507
+ window.onerror = oldOnerror;
508
+ });
509
+ });
99
510
  //# sourceMappingURL=tabs.test.js.map