@muonic/muon 0.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.nycrc +17 -0
  2. package/.versionrc +3 -0
  3. package/CHANGELOG.md +389 -0
  4. package/components/card/index.js +1 -0
  5. package/components/card/src/card-component.js +43 -0
  6. package/components/card/src/card-styles.css +25 -0
  7. package/components/card/src/config-tokens.json +11 -0
  8. package/components/card/src/design-tokens.json +34 -0
  9. package/components/card/story.js +52 -0
  10. package/components/cta/index.js +1 -0
  11. package/components/cta/src/config-tokens.json +11 -0
  12. package/components/cta/src/cta-component.js +174 -0
  13. package/components/cta/src/cta-styles.css +105 -0
  14. package/components/cta/src/design-tokens.json +132 -0
  15. package/components/cta/story.js +99 -0
  16. package/components/detail/index.js +1 -0
  17. package/components/detail/src/config-tokens.json +11 -0
  18. package/components/detail/src/design-tokens.json +102 -0
  19. package/components/detail/src/detail-component.js +27 -0
  20. package/components/detail/src/detail-styles.css +83 -0
  21. package/components/detail/story.js +33 -0
  22. package/components/form/index.js +1 -0
  23. package/components/form/src/config-tokens.json +11 -0
  24. package/components/form/src/design-tokens.json +9 -0
  25. package/components/form/src/form-component.js +197 -0
  26. package/components/form/src/form-styles.css +10 -0
  27. package/components/form/story.js +71 -0
  28. package/components/icon/index.js +1 -0
  29. package/components/icon/src/config-tokens.json +31 -0
  30. package/components/icon/src/design-tokens.json +8 -0
  31. package/components/icon/src/icon-component.js +91 -0
  32. package/components/icon/src/icon-styles.css +26 -0
  33. package/components/icon/story.js +26 -0
  34. package/components/image/index.js +1 -0
  35. package/components/image/src/config-tokens.json +26 -0
  36. package/components/image/src/image-component.js +96 -0
  37. package/components/image/src/image-styles.css +71 -0
  38. package/components/image/story.js +31 -0
  39. package/components/inputter/index.js +1 -0
  40. package/components/inputter/src/config-tokens.json +14 -0
  41. package/components/inputter/src/design-tokens.json +308 -0
  42. package/components/inputter/src/inputter-component.js +227 -0
  43. package/components/inputter/src/inputter-styles-detail.css +59 -0
  44. package/components/inputter/src/inputter-styles.css +305 -0
  45. package/components/inputter/src/inputter-styles.slotted.css +64 -0
  46. package/components/inputter/story.js +243 -0
  47. package/css/accessibility.css +3 -0
  48. package/css/default.css +9 -0
  49. package/css/global.css +8 -0
  50. package/directives/image-loader-directive.js +116 -0
  51. package/directives/svg-loader-directive.js +94 -0
  52. package/index.js +52 -0
  53. package/mixins/card-mixin.js +27 -0
  54. package/mixins/detail-mixin.js +128 -0
  55. package/mixins/form-associate-mixin.js +36 -0
  56. package/mixins/form-element-mixin.js +378 -0
  57. package/mixins/image-holder-mixin.js +20 -0
  58. package/mixins/mask-mixin.js +159 -0
  59. package/mixins/validation-mixin.js +272 -0
  60. package/muon-element/index.js +97 -0
  61. package/package.json +72 -0
  62. package/rollup.config.mjs +30 -0
  63. package/scripts/build/storybook/index.mjs +11 -0
  64. package/scripts/build/storybook/run.mjs +47 -0
  65. package/scripts/rollup-plugins.mjs +116 -0
  66. package/scripts/serve/index.mjs +11 -0
  67. package/scripts/serve/run.mjs +27 -0
  68. package/scripts/style-dictionary.mjs +64 -0
  69. package/scripts/utils/config.mjs +30 -0
  70. package/scripts/utils/index.mjs +283 -0
  71. package/storybook/find-stories.js +36 -0
  72. package/storybook/server.config.mjs +19 -0
  73. package/storybook/stories.js +86 -0
  74. package/storybook/tokens/color.js +87 -0
  75. package/storybook/tokens/font.js +52 -0
  76. package/storybook/tokens/spacer.js +48 -0
  77. package/tests/README.md +3 -0
  78. package/tests/components/card/__snapshots__/card.test.snap.js +70 -0
  79. package/tests/components/card/card.test.js +81 -0
  80. package/tests/components/cta/__snapshots__/cta.test.snap.js +246 -0
  81. package/tests/components/cta/cta.test.js +212 -0
  82. package/tests/components/form/__snapshots__/form.test.snap.js +115 -0
  83. package/tests/components/form/form.test.js +336 -0
  84. package/tests/components/icon/__snapshots__/icon.test.snap.js +95 -0
  85. package/tests/components/icon/icon.test.js +197 -0
  86. package/tests/components/image/__snapshots__/image.test.snap.js +205 -0
  87. package/tests/components/image/image.test.js +314 -0
  88. package/tests/components/image/images/15.png +0 -0
  89. package/tests/components/image/images/150.png +0 -0
  90. package/tests/components/inputter/__snapshots__/inputter.test.snap.js +357 -0
  91. package/tests/components/inputter/inputter.test.js +427 -0
  92. package/tests/helpers/index.js +30 -0
  93. package/tests/mixins/__snapshots__/card.test.snap.js +35 -0
  94. package/tests/mixins/__snapshots__/detail.test.snap.js +237 -0
  95. package/tests/mixins/__snapshots__/form-element.test.snap.js +137 -0
  96. package/tests/mixins/__snapshots__/mask.test.snap.js +53 -0
  97. package/tests/mixins/__snapshots__/validation.test.snap.js +297 -0
  98. package/tests/mixins/card.test.js +63 -0
  99. package/tests/mixins/detail.test.js +223 -0
  100. package/tests/mixins/form-element.test.js +473 -0
  101. package/tests/mixins/mask.test.js +261 -0
  102. package/tests/mixins/muon-element.test.js +52 -0
  103. package/tests/mixins/validation.test.js +423 -0
  104. package/tests/runner/commands.mjs +19 -0
  105. package/tests/scripts/utils/card-component.js +26 -0
  106. package/tests/scripts/utils/muon.config.test.json +13 -0
  107. package/tests/scripts/utils/single.component.config.json +5 -0
  108. package/tests/scripts/utils/test-runner.mjs +1 -0
  109. package/tests/scripts/utils/utils-test.mjs +284 -0
  110. package/tests/utils/validation.functions.test.js +199 -0
  111. package/tokens/theme/color.json +482 -0
  112. package/tokens/theme/font.json +61 -0
  113. package/tokens/theme/size.json +27 -0
  114. package/tokens/theme/spacer.json +73 -0
  115. package/tokens/utils/formats/reference.js +17 -0
  116. package/tokens/utils/modular-scale.js +33 -0
  117. package/tokens/utils/templates/font-face.css.template +30 -0
  118. package/tokens/utils/transforms/color.js +27 -0
  119. package/tokens/utils/transforms/string.js +6 -0
  120. package/tokens/utils/validation.json +76 -0
  121. package/utils/scroll/index.js +31 -0
  122. package/utils/validation/index.js +205 -0
  123. package/web-test-runner.browserstack.config.mjs +123 -0
  124. package/web-test-runner.config.mjs +44 -0
@@ -0,0 +1,297 @@
1
+ /* @web/test-runner snapshot v1 */
2
+ export const snapshots = {};
3
+
4
+ snapshots["form-element standard"] =
5
+ `<div class="slotted-content">
6
+ <slot name="label">
7
+ </slot>
8
+ <div class="input-holder">
9
+ <slot>
10
+ </slot>
11
+ </div>
12
+ </div>
13
+ `;
14
+ /* end snapshot form-element standard */
15
+
16
+ snapshots["form-element standard onchange validation"] =
17
+ `<div class="slotted-content">
18
+ <slot name="label">
19
+ </slot>
20
+ <div class="input-holder">
21
+ <slot>
22
+ </slot>
23
+ </div>
24
+ </div>
25
+ `;
26
+ /* end snapshot form-element standard onchange validation */
27
+
28
+ snapshots["form-element text onchange validation"] =
29
+ `<div class="slotted-content">
30
+ <slot name="label">
31
+ </slot>
32
+ <div class="input-holder">
33
+ <slot>
34
+ </slot>
35
+ </div>
36
+ </div>
37
+ `;
38
+ /* end snapshot form-element text onchange validation */
39
+
40
+ snapshots["form-element radio onchange validation"] =
41
+ `<div class="slotted-content">
42
+ <span class="input-heading">
43
+ What is your heating source?
44
+ </span>
45
+ <div class="input-holder">
46
+ <slot>
47
+ </slot>
48
+ </div>
49
+ </div>
50
+ `;
51
+ /* end snapshot form-element radio onchange validation */
52
+
53
+ snapshots["form-element checkbox onblur validation"] =
54
+ `<div class="slotted-content">
55
+ <span class="input-heading">
56
+ What is your heating source?
57
+ </span>
58
+ <div class="input-holder">
59
+ <slot>
60
+ </slot>
61
+ </div>
62
+ </div>
63
+ `;
64
+ /* end snapshot form-element checkbox onblur validation */
65
+
66
+ snapshots["form-element text validation"] =
67
+ `<div class="slotted-content">
68
+ <slot name="label">
69
+ </slot>
70
+ <div class="input-holder">
71
+ <slot>
72
+ </slot>
73
+ </div>
74
+ </div>
75
+ `;
76
+ /* end snapshot form-element text validation */
77
+
78
+ snapshots["form-element radio validation"] =
79
+ `<div class="slotted-content">
80
+ <span class="input-heading">
81
+ What is your heating source?
82
+ </span>
83
+ <div class="input-holder">
84
+ <slot>
85
+ </slot>
86
+ </div>
87
+ </div>
88
+ `;
89
+ /* end snapshot form-element radio validation */
90
+
91
+ snapshots["form-element checkbox validation"] =
92
+ `<div class="slotted-content">
93
+ <span class="input-heading">
94
+ What is your heating source?
95
+ </span>
96
+ <div class="input-holder">
97
+ <slot>
98
+ </slot>
99
+ </div>
100
+ </div>
101
+ `;
102
+ /* end snapshot form-element checkbox validation */
103
+
104
+ snapshots["form-element select validation"] =
105
+ `<div class="slotted-content">
106
+ <slot name="label">
107
+ </slot>
108
+ <div class="input-holder">
109
+ <slot>
110
+ </slot>
111
+ </div>
112
+ </div>
113
+ `;
114
+ /* end snapshot form-element select validation */
115
+
116
+ snapshots["form-element text extended validation"] =
117
+ `<div class="slotted-content">
118
+ <slot name="label">
119
+ </slot>
120
+ <div class="input-holder">
121
+ <slot>
122
+ </slot>
123
+ </div>
124
+ </div>
125
+ `;
126
+ /* end snapshot form-element text extended validation */
127
+
128
+ snapshots["form-element text native validation"] =
129
+ `<div class="slotted-content">
130
+ <slot name="label">
131
+ </slot>
132
+ <div class="input-holder">
133
+ <slot>
134
+ </slot>
135
+ </div>
136
+ </div>
137
+ `;
138
+ /* end snapshot form-element text native validation */
139
+
140
+ snapshots["form-element text list validation"] =
141
+ `<div class="slotted-content">
142
+ <slot name="label">
143
+ </slot>
144
+ <div class="input-holder">
145
+ <slot>
146
+ </slot>
147
+ </div>
148
+ </div>
149
+ `;
150
+ /* end snapshot form-element text list validation */
151
+
152
+ snapshots["form-element text custom type validation"] =
153
+ `<div class="slotted-content">
154
+ <slot name="label">
155
+ </slot>
156
+ <div class="input-holder">
157
+ <slot>
158
+ </slot>
159
+ </div>
160
+ </div>
161
+ `;
162
+ /* end snapshot form-element text custom type validation */
163
+
164
+ snapshots["form-element-validation standard"] =
165
+ `<div class="slotted-content">
166
+ <slot name="label">
167
+ </slot>
168
+ <div class="input-holder">
169
+ <slot>
170
+ </slot>
171
+ </div>
172
+ </div>
173
+ `;
174
+ /* end snapshot form-element-validation standard */
175
+
176
+ snapshots["form-element-validation text validation"] =
177
+ `<div class="slotted-content">
178
+ <slot name="label">
179
+ </slot>
180
+ <div class="input-holder">
181
+ <slot>
182
+ </slot>
183
+ </div>
184
+ </div>
185
+ `;
186
+ /* end snapshot form-element-validation text validation */
187
+
188
+ snapshots["form-element-validation text extended validation"] =
189
+ `<div class="slotted-content">
190
+ <slot name="label">
191
+ </slot>
192
+ <div class="input-holder">
193
+ <slot>
194
+ </slot>
195
+ </div>
196
+ </div>
197
+ `;
198
+ /* end snapshot form-element-validation text extended validation */
199
+
200
+ snapshots["form-element-validation text native validation"] =
201
+ `<div class="slotted-content">
202
+ <slot name="label">
203
+ </slot>
204
+ <div class="input-holder">
205
+ <slot>
206
+ </slot>
207
+ </div>
208
+ </div>
209
+ `;
210
+ /* end snapshot form-element-validation text native validation */
211
+
212
+ snapshots["form-element-validation text custom type validation"] =
213
+ `<div class="slotted-content">
214
+ <slot name="label">
215
+ </slot>
216
+ <div class="input-holder">
217
+ <slot>
218
+ </slot>
219
+ </div>
220
+ </div>
221
+ `;
222
+ /* end snapshot form-element-validation text custom type validation */
223
+
224
+ snapshots["form-element-validation radio validation"] =
225
+ `<div class="slotted-content">
226
+ <span class="input-heading">
227
+ What is your heating source?
228
+ </span>
229
+ <div class="input-holder">
230
+ <slot>
231
+ </slot>
232
+ </div>
233
+ </div>
234
+ `;
235
+ /* end snapshot form-element-validation radio validation */
236
+
237
+ snapshots["form-element-validation checkbox validation"] =
238
+ `<div class="slotted-content">
239
+ <span class="input-heading">
240
+ What is your heating source?
241
+ </span>
242
+ <div class="input-holder">
243
+ <slot>
244
+ </slot>
245
+ </div>
246
+ </div>
247
+ `;
248
+ /* end snapshot form-element-validation checkbox validation */
249
+
250
+ snapshots["form-element-validation select validation"] =
251
+ `<div class="slotted-content">
252
+ <slot name="label">
253
+ </slot>
254
+ <div class="input-holder">
255
+ <slot>
256
+ </slot>
257
+ </div>
258
+ </div>
259
+ `;
260
+ /* end snapshot form-element-validation select validation */
261
+
262
+ snapshots["form-element-validation date validation"] =
263
+ `<div class="slotted-content">
264
+ <slot name="label">
265
+ </slot>
266
+ <div class="input-holder">
267
+ <slot>
268
+ </slot>
269
+ </div>
270
+ </div>
271
+ `;
272
+ /* end snapshot form-element-validation date validation */
273
+
274
+ snapshots["form-element-validation tel native validation"] =
275
+ `<div class="slotted-content">
276
+ <slot name="label">
277
+ </slot>
278
+ <div class="input-holder">
279
+ <slot>
280
+ </slot>
281
+ </div>
282
+ </div>
283
+ `;
284
+ /* end snapshot form-element-validation tel native validation */
285
+
286
+ snapshots["form-element-validation text validation on input"] =
287
+ `<div class="slotted-content">
288
+ <slot name="label">
289
+ </slot>
290
+ <div class="input-holder">
291
+ <slot>
292
+ </slot>
293
+ </div>
294
+ </div>
295
+ `;
296
+ /* end snapshot form-element-validation text validation on input */
297
+
@@ -0,0 +1,63 @@
1
+ /* eslint-disable no-undef */
2
+ import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
3
+ import { MuonElement } from '@muonic/muon';
4
+ import { defaultChecks } from '../helpers';
5
+ import { CardMixin } from '@muonic/muon/mixins/card-mixin';
6
+ import { Cta } from '@muonic/muon/components/cta';
7
+
8
+ const CardMixinElement = class extends CardMixin(MuonElement) {
9
+
10
+ get standardTemplate() {
11
+ return html`
12
+ ${this._addHeader}
13
+ ${this._addContent}
14
+ ${this._addFooter}
15
+ `;
16
+ }
17
+ };
18
+
19
+ const tagName = defineCE(CardMixinElement);
20
+ const tag = unsafeStatic(tagName);
21
+
22
+ const ctaTag = unsafeStatic(defineCE(Cta));
23
+
24
+ describe('card', async () => {
25
+ it('default', async () => {
26
+ const cardElement = await fixture(html`<${tag}></${tag}>`);
27
+ await defaultChecks(cardElement);
28
+
29
+ const shadowRoot = cardElement.shadowRoot;
30
+
31
+ expect(shadowRoot.querySelector('.header')).to.not.be.null; // eslint-disable-line no-unused-expressions
32
+ expect(shadowRoot.querySelector('.content')).to.not.be.null; // eslint-disable-line no-unused-expressions
33
+ expect(shadowRoot.querySelector('.footer')).to.not.be.null; // eslint-disable-line no-unused-expressions
34
+ });
35
+
36
+ it('standard', async () => {
37
+ const cardElement = await fixture(html`
38
+ <${tag}>
39
+ <h2 slot="header">Heating services</h2>
40
+ <p>Product and services we offer for energy in your home</p>
41
+ <${ctaTag} slot="footer">Click Here</${ctaTag}>
42
+ </${tag}>`);
43
+ await defaultChecks(cardElement);
44
+
45
+ const shadowRoot = cardElement.shadowRoot;
46
+
47
+ const headerSelector = shadowRoot.querySelector('.header');
48
+ expect(headerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
49
+ const header = headerSelector.querySelector('slot[name="header"]');
50
+ expect(header.assignedElements()[0].textContent).to.equal('Heating services', 'Heading slot value matches');
51
+
52
+ const content = shadowRoot.querySelector('.content');
53
+ expect(shadowRoot.querySelector('.content')).to.not.be.null; // eslint-disable-line no-unused-expressions
54
+ const paragraph = content.querySelector('slot');
55
+ expect(paragraph.assignedElements()[0].textContent).to.equal('Product and services we offer for energy in your home', 'Content slot value matches');
56
+
57
+ const footerSelector = shadowRoot.querySelector('.footer');
58
+ expect(footerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
59
+ const cta = footerSelector.querySelector('slot[name="footer"]');
60
+ expect(cta.assignedElements()[0].textContent).to.equal('Click Here', 'Action slot has Cta component');
61
+
62
+ });
63
+ });
@@ -0,0 +1,223 @@
1
+ /* eslint-disable no-undef */
2
+ import { expect, fixture, html, defineCE, unsafeStatic, waitUntil } from '@open-wc/testing';
3
+ import { MuonElement } from '@muonic/muon';
4
+ import sinon from 'sinon';
5
+ import { defaultChecks } from '../helpers';
6
+ import { DetailMixin } from '@muonic/muon/mixins/detail-mixin';
7
+ import { Detail } from '@muonic/muon/components/detail';
8
+
9
+ const MuonDetailElement = class extends DetailMixin(MuonElement) {};
10
+
11
+ const TestDetailElement = class extends DetailMixin(MuonElement) {
12
+ constructor() {
13
+ super();
14
+
15
+ this._toggleOpen = 'chevron-circle-down';
16
+ this._toggleClose = 'chevron-circle-up';
17
+ this._togglePosition = 'start';
18
+ }
19
+ };
20
+
21
+ const tagName = defineCE(MuonDetailElement);
22
+ const tag = unsafeStatic(tagName);
23
+ const withIconTagName = defineCE(TestDetailElement);
24
+ const withIconTag = unsafeStatic(withIconTagName);
25
+
26
+ describe('detail', () => {
27
+ afterEach(() => {
28
+ sinon.restore();
29
+ });
30
+
31
+ it('standard', async () => {
32
+ const detailElement = await fixture(html`<${tag}></${tag}>`);
33
+ await defaultChecks(detailElement);
34
+
35
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
36
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
37
+ const shadowRoot = detailElement.shadowRoot;
38
+ const detail = shadowRoot.querySelector('details');
39
+
40
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
41
+ expect(detail.open).to.equal(false, '`open` attribute has correct value `false`');
42
+ });
43
+
44
+ it('standard open', async () => {
45
+ const detailElement = await fixture(html`<${tag} open></${tag}>`);
46
+ await defaultChecks(detailElement);
47
+
48
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
49
+ expect(detailElement.open).to.equal(true, '`open` property has default value `true`');
50
+ const shadowRoot = detailElement.shadowRoot;
51
+ const detail = shadowRoot.querySelector('details');
52
+
53
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
54
+ expect(detail.open).to.equal(true, '`open` property has correct value `true`');
55
+ });
56
+
57
+ it('standard icon', async () => {
58
+ const detailElement = await fixture(html`<${tag} icon="dot-circle"></${tag}>`);
59
+ await defaultChecks(detailElement);
60
+
61
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
62
+ const shadowRoot = detailElement.shadowRoot;
63
+ const detail = shadowRoot.querySelector('details');
64
+
65
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
66
+ const icon = detail.querySelector('.icon');
67
+ expect(icon).to.not.be.null; // eslint-disable-line no-unused-expressions
68
+ expect(icon.name).to.equal('dot-circle', '`icon` property has correct value');
69
+ });
70
+
71
+ it('standard slotted content', async () => {
72
+ const detailElement = await fixture(html`
73
+ <${tag}>
74
+ <h3 slot="heading">Where can I buy an ice cream?</h3>
75
+ <p>
76
+ fjkbdkf dfnbkdf udbkfgdkjf
77
+ </p>
78
+ </${tag}>`);
79
+ await defaultChecks(detailElement);
80
+
81
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
82
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
83
+ const shadowRoot = detailElement.shadowRoot;
84
+ const detail = shadowRoot.querySelector('details');
85
+
86
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
87
+ expect(detail.open).to.equal(false, '`open` property has correct value `false`');
88
+
89
+ const toggleEventSpy = sinon.spy();
90
+ detailElement.addEventListener('toggle', toggleEventSpy);
91
+
92
+ const summary = detail.querySelector('.heading');
93
+ const heading = summary.querySelector('slot[name="heading"]');
94
+
95
+ expect(heading).to.not.be.null; // eslint-disable-line no-unused-expressions
96
+ expect(heading.assignedElements()[0].textContent).to.equal('Where can I buy an ice cream?', '`heading` slot has value `What is your heating source?`');
97
+
98
+ const content = detail.querySelector('.content > slot');
99
+ expect(content).to.not.be.null; // eslint-disable-line no-unused-expressions
100
+ expect(content.assignedElements()[0].textContent.trim()).to.equal('fjkbdkf dfnbkdf udbkfgdkjf', '`heading` slot has value `What is your heating source?`');
101
+ });
102
+
103
+ it('standard toggle event true', async () => {
104
+ const detailElement = await fixture(html`
105
+ <${tag}>
106
+ <h3 slot="heading">Where can I buy an ice cream?</h3>
107
+ <p>
108
+ fjkbdkf dfnbkdf udbkfgdkjf
109
+ </p>
110
+ </${tag}>`);
111
+ await defaultChecks(detailElement);
112
+
113
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
114
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
115
+ const shadowRoot = detailElement.shadowRoot;
116
+ const detail = shadowRoot.querySelector('details');
117
+
118
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
119
+ expect(detail.open).to.equal(false, '`open` property has correct value `false`');
120
+
121
+ const toggleEventSpy = sinon.spy();
122
+ detailElement.addEventListener('detail-toggle', toggleEventSpy);
123
+
124
+ const summary = detail.querySelector('.heading');
125
+ const heading = summary.querySelector('slot[name="heading"]');
126
+
127
+ expect(heading).to.not.be.null; // eslint-disable-line no-unused-expressions
128
+
129
+ summary.click();
130
+
131
+ await waitUntil(() => detailElement.open);
132
+ expect(detailElement.open).to.equal(true, '`open` property has default value `true`');
133
+ expect(detail.open).to.equal(true, '`open` property has correct value `true`');
134
+ expect(toggleEventSpy.callCount).to.equal(1, '`toggle` event fired');
135
+ expect(toggleEventSpy.lastCall.args[0].detail.open).to.equal(true, '`toggle` event has isOpen `true`');
136
+ });
137
+
138
+ it('standard toggle event false', async () => {
139
+ const detailElement = await fixture(html`
140
+ <${withIconTag} open>
141
+ <h3 slot="heading">Where can I buy an ice cream?</h3>
142
+ <p>
143
+ fjkbdkf dfnbkdf udbkfgdkjf
144
+ </p>
145
+ </${withIconTag}>`);
146
+ await defaultChecks(detailElement);
147
+
148
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
149
+ expect(detailElement.open).to.equal(true, '`open` property has default value `true`');
150
+ const shadowRoot = detailElement.shadowRoot;
151
+ const detail = shadowRoot.querySelector('details');
152
+
153
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
154
+ expect(detail.open).to.equal(true, '`open` property has correct value `true`');
155
+
156
+ const toggleEventSpy = sinon.spy();
157
+ detailElement.addEventListener('detail-toggle', toggleEventSpy);
158
+
159
+ const summary = detail.querySelector('.heading');
160
+ const heading = summary.querySelector('slot[name="heading"]');
161
+
162
+ expect(heading).to.not.be.null; // eslint-disable-line no-unused-expressions
163
+
164
+ summary.click();
165
+
166
+ await waitUntil(() => !detailElement.open);
167
+
168
+ expect(detail.open).to.equal(false, '`open` property has correct value `false`');
169
+ expect(toggleEventSpy.callCount).to.equal(1, '`toggle` event fired');
170
+ expect(toggleEventSpy.lastCall.args[0].detail.open).to.equal(false, '`toggle` event has open `false`');
171
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
172
+ });
173
+
174
+ it('standard toggle', async () => {
175
+ const detailElement = await fixture(html`<${withIconTag}></${withIconTag}>`);
176
+ await defaultChecks(detailElement);
177
+
178
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
179
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
180
+ const shadowRoot = detailElement.shadowRoot;
181
+ const detail = shadowRoot.querySelector('.details.toggle-start');
182
+
183
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
184
+ expect(detail.open).to.equal(false, '`open` attribute has correct value `false`');
185
+
186
+ const toggleIcon = detail.querySelector('.toggle');
187
+ expect(toggleIcon).to.not.be.null; // eslint-disable-line no-unused-expressions
188
+ expect(toggleIcon.name).to.equal('chevron-circle-down', '`toggleIcon` has correct value `chevron-circle-down`');
189
+ expect(toggleIcon.nextElementSibling.name).to.equal('heading');
190
+
191
+ const summary = detail.querySelector('.heading');
192
+ summary.click();
193
+
194
+ await waitUntil(() => detailElement.open);
195
+ expect(toggleIcon.name).to.equal('chevron-circle-up', '`toggleIcon` has correct value `chevron-circle-up`');
196
+ });
197
+
198
+ it('standard toggle end', async () => {
199
+ const tagName = defineCE(Detail);
200
+ const tag = unsafeStatic(tagName);
201
+ const detailElement = await fixture(html`<${tag}></${tag}>`);
202
+ await defaultChecks(detailElement);
203
+
204
+ expect(detailElement.type).to.equal('standard', '`type` property has default value `standard`');
205
+ expect(detailElement.open).to.equal(false, '`open` property has default value `false`');
206
+ const shadowRoot = detailElement.shadowRoot;
207
+ const detail = shadowRoot.querySelector('.details.toggle-end');
208
+
209
+ expect(detail).to.not.be.null; // eslint-disable-line no-unused-expressions
210
+ expect(detail.open).to.equal(false, '`open` attribute has correct value `false`');
211
+
212
+ const toggleIcon = detail.querySelector('.toggle');
213
+ expect(toggleIcon).to.not.be.null; // eslint-disable-line no-unused-expressions
214
+ expect(toggleIcon.name).to.equal('chevron-circle-down', '`toggleIcon` has correct value `chevron-circle-down`');
215
+ expect(toggleIcon.previousElementSibling.name).to.equal('heading');
216
+
217
+ const summary = detail.querySelector('.heading');
218
+ summary.click();
219
+
220
+ await waitUntil(() => detailElement.open);
221
+ expect(toggleIcon.name).to.equal('chevron-circle-up', '`toggleIcon` has correct value `chevron-circle-up`');
222
+ });
223
+ });