@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.
- package/.nycrc +17 -0
- package/.versionrc +3 -0
- package/CHANGELOG.md +389 -0
- package/components/card/index.js +1 -0
- package/components/card/src/card-component.js +43 -0
- package/components/card/src/card-styles.css +25 -0
- package/components/card/src/config-tokens.json +11 -0
- package/components/card/src/design-tokens.json +34 -0
- package/components/card/story.js +52 -0
- package/components/cta/index.js +1 -0
- package/components/cta/src/config-tokens.json +11 -0
- package/components/cta/src/cta-component.js +174 -0
- package/components/cta/src/cta-styles.css +105 -0
- package/components/cta/src/design-tokens.json +132 -0
- package/components/cta/story.js +99 -0
- package/components/detail/index.js +1 -0
- package/components/detail/src/config-tokens.json +11 -0
- package/components/detail/src/design-tokens.json +102 -0
- package/components/detail/src/detail-component.js +27 -0
- package/components/detail/src/detail-styles.css +83 -0
- package/components/detail/story.js +33 -0
- package/components/form/index.js +1 -0
- package/components/form/src/config-tokens.json +11 -0
- package/components/form/src/design-tokens.json +9 -0
- package/components/form/src/form-component.js +197 -0
- package/components/form/src/form-styles.css +10 -0
- package/components/form/story.js +71 -0
- package/components/icon/index.js +1 -0
- package/components/icon/src/config-tokens.json +31 -0
- package/components/icon/src/design-tokens.json +8 -0
- package/components/icon/src/icon-component.js +91 -0
- package/components/icon/src/icon-styles.css +26 -0
- package/components/icon/story.js +26 -0
- package/components/image/index.js +1 -0
- package/components/image/src/config-tokens.json +26 -0
- package/components/image/src/image-component.js +96 -0
- package/components/image/src/image-styles.css +71 -0
- package/components/image/story.js +31 -0
- package/components/inputter/index.js +1 -0
- package/components/inputter/src/config-tokens.json +14 -0
- package/components/inputter/src/design-tokens.json +308 -0
- package/components/inputter/src/inputter-component.js +227 -0
- package/components/inputter/src/inputter-styles-detail.css +59 -0
- package/components/inputter/src/inputter-styles.css +305 -0
- package/components/inputter/src/inputter-styles.slotted.css +64 -0
- package/components/inputter/story.js +243 -0
- package/css/accessibility.css +3 -0
- package/css/default.css +9 -0
- package/css/global.css +8 -0
- package/directives/image-loader-directive.js +116 -0
- package/directives/svg-loader-directive.js +94 -0
- package/index.js +52 -0
- package/mixins/card-mixin.js +27 -0
- package/mixins/detail-mixin.js +128 -0
- package/mixins/form-associate-mixin.js +36 -0
- package/mixins/form-element-mixin.js +378 -0
- package/mixins/image-holder-mixin.js +20 -0
- package/mixins/mask-mixin.js +159 -0
- package/mixins/validation-mixin.js +272 -0
- package/muon-element/index.js +97 -0
- package/package.json +72 -0
- package/rollup.config.mjs +30 -0
- package/scripts/build/storybook/index.mjs +11 -0
- package/scripts/build/storybook/run.mjs +47 -0
- package/scripts/rollup-plugins.mjs +116 -0
- package/scripts/serve/index.mjs +11 -0
- package/scripts/serve/run.mjs +27 -0
- package/scripts/style-dictionary.mjs +64 -0
- package/scripts/utils/config.mjs +30 -0
- package/scripts/utils/index.mjs +283 -0
- package/storybook/find-stories.js +36 -0
- package/storybook/server.config.mjs +19 -0
- package/storybook/stories.js +86 -0
- package/storybook/tokens/color.js +87 -0
- package/storybook/tokens/font.js +52 -0
- package/storybook/tokens/spacer.js +48 -0
- package/tests/README.md +3 -0
- package/tests/components/card/__snapshots__/card.test.snap.js +70 -0
- package/tests/components/card/card.test.js +81 -0
- package/tests/components/cta/__snapshots__/cta.test.snap.js +246 -0
- package/tests/components/cta/cta.test.js +212 -0
- package/tests/components/form/__snapshots__/form.test.snap.js +115 -0
- package/tests/components/form/form.test.js +336 -0
- package/tests/components/icon/__snapshots__/icon.test.snap.js +95 -0
- package/tests/components/icon/icon.test.js +197 -0
- package/tests/components/image/__snapshots__/image.test.snap.js +205 -0
- package/tests/components/image/image.test.js +314 -0
- package/tests/components/image/images/15.png +0 -0
- package/tests/components/image/images/150.png +0 -0
- package/tests/components/inputter/__snapshots__/inputter.test.snap.js +357 -0
- package/tests/components/inputter/inputter.test.js +427 -0
- package/tests/helpers/index.js +30 -0
- package/tests/mixins/__snapshots__/card.test.snap.js +35 -0
- package/tests/mixins/__snapshots__/detail.test.snap.js +237 -0
- package/tests/mixins/__snapshots__/form-element.test.snap.js +137 -0
- package/tests/mixins/__snapshots__/mask.test.snap.js +53 -0
- package/tests/mixins/__snapshots__/validation.test.snap.js +297 -0
- package/tests/mixins/card.test.js +63 -0
- package/tests/mixins/detail.test.js +223 -0
- package/tests/mixins/form-element.test.js +473 -0
- package/tests/mixins/mask.test.js +261 -0
- package/tests/mixins/muon-element.test.js +52 -0
- package/tests/mixins/validation.test.js +423 -0
- package/tests/runner/commands.mjs +19 -0
- package/tests/scripts/utils/card-component.js +26 -0
- package/tests/scripts/utils/muon.config.test.json +13 -0
- package/tests/scripts/utils/single.component.config.json +5 -0
- package/tests/scripts/utils/test-runner.mjs +1 -0
- package/tests/scripts/utils/utils-test.mjs +284 -0
- package/tests/utils/validation.functions.test.js +199 -0
- package/tokens/theme/color.json +482 -0
- package/tokens/theme/font.json +61 -0
- package/tokens/theme/size.json +27 -0
- package/tokens/theme/spacer.json +73 -0
- package/tokens/utils/formats/reference.js +17 -0
- package/tokens/utils/modular-scale.js +33 -0
- package/tokens/utils/templates/font-face.css.template +30 -0
- package/tokens/utils/transforms/color.js +27 -0
- package/tokens/utils/transforms/string.js +6 -0
- package/tokens/utils/validation.json +76 -0
- package/utils/scroll/index.js +31 -0
- package/utils/validation/index.js +205 -0
- package/web-test-runner.browserstack.config.mjs +123 -0
- package/web-test-runner.config.mjs +44 -0
package/tests/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* @web/test-runner snapshot v1 */
|
|
2
|
+
export const snapshots = {};
|
|
3
|
+
|
|
4
|
+
snapshots["card default"] =
|
|
5
|
+
`<div class="card">
|
|
6
|
+
<div class="body">
|
|
7
|
+
<div class="header">
|
|
8
|
+
<slot name="header">
|
|
9
|
+
</slot>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="content">
|
|
12
|
+
<slot>
|
|
13
|
+
</slot>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="footer">
|
|
16
|
+
<slot name="footer">
|
|
17
|
+
</slot>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
`;
|
|
22
|
+
/* end snapshot card default */
|
|
23
|
+
|
|
24
|
+
snapshots["card standard"] =
|
|
25
|
+
`<div class="card">
|
|
26
|
+
<div class="body">
|
|
27
|
+
<div class="header">
|
|
28
|
+
<slot name="header">
|
|
29
|
+
</slot>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="content">
|
|
32
|
+
<slot>
|
|
33
|
+
</slot>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="footer">
|
|
36
|
+
<slot name="footer">
|
|
37
|
+
</slot>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
`;
|
|
42
|
+
/* end snapshot card standard */
|
|
43
|
+
|
|
44
|
+
snapshots["card standard with image"] =
|
|
45
|
+
`<div class="card">
|
|
46
|
+
<div class="media">
|
|
47
|
+
<card-image
|
|
48
|
+
alt="image alt"
|
|
49
|
+
src="tests/components/image/images/150.png"
|
|
50
|
+
>
|
|
51
|
+
</card-image>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="body">
|
|
54
|
+
<div class="header">
|
|
55
|
+
<slot name="header">
|
|
56
|
+
</slot>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="content">
|
|
59
|
+
<slot>
|
|
60
|
+
</slot>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="footer">
|
|
63
|
+
<slot name="footer">
|
|
64
|
+
</slot>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
`;
|
|
69
|
+
/* end snapshot card standard with image */
|
|
70
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
|
|
3
|
+
import { defaultChecks } from '../../helpers';
|
|
4
|
+
import { Card } from '@muonic/muon/components/card';
|
|
5
|
+
|
|
6
|
+
const tag = unsafeStatic(defineCE(Card));
|
|
7
|
+
|
|
8
|
+
describe('card', async () => {
|
|
9
|
+
it('default', async () => {
|
|
10
|
+
const cardElement = await fixture(html`<${tag}></${tag}>`);
|
|
11
|
+
await defaultChecks(cardElement);
|
|
12
|
+
|
|
13
|
+
const shadowRoot = cardElement.shadowRoot;
|
|
14
|
+
|
|
15
|
+
expect(shadowRoot.querySelector('.header')).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
16
|
+
expect(shadowRoot.querySelector('.content')).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
17
|
+
expect(shadowRoot.querySelector('.footer')).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('standard', async () => {
|
|
21
|
+
const cardElement = await fixture(html`
|
|
22
|
+
<${tag}>
|
|
23
|
+
<h2 slot="header">Heating services</h2>
|
|
24
|
+
<p>Product and services we offer for energy in your home</p>
|
|
25
|
+
<div slot="footer">Footnote</div>
|
|
26
|
+
</${tag}>`);
|
|
27
|
+
await defaultChecks(cardElement);
|
|
28
|
+
|
|
29
|
+
const shadowRoot = cardElement.shadowRoot;
|
|
30
|
+
|
|
31
|
+
const headerSelector = shadowRoot.querySelector('.header');
|
|
32
|
+
expect(headerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
33
|
+
const header = headerSelector.querySelector('slot[name="header"]');
|
|
34
|
+
expect(header.assignedElements()[0].textContent).to.equal('Heating services', 'Heading slot value matches');
|
|
35
|
+
|
|
36
|
+
const content = shadowRoot.querySelector('.content');
|
|
37
|
+
expect(shadowRoot.querySelector('.content')).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
38
|
+
const paragraph = content.querySelector('slot');
|
|
39
|
+
expect(paragraph.assignedElements()[0].textContent).to.equal('Product and services we offer for energy in your home', 'Content slot value matches');
|
|
40
|
+
|
|
41
|
+
const footerSelector = shadowRoot.querySelector('.footer');
|
|
42
|
+
expect(footerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
43
|
+
const footer = footerSelector.querySelector('slot[name="footer"]');
|
|
44
|
+
expect(footer.assignedElements()[0].textContent).to.equal('Footnote', 'Footer slot value matches');
|
|
45
|
+
|
|
46
|
+
expect(shadowRoot.querySelector('.media')).to.be.null; // eslint-disable-line no-unused-expressions
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('standard with image', async () => {
|
|
50
|
+
const cardElement = await fixture(html`
|
|
51
|
+
<${tag} image="tests/components/image/images/150.png" alt="image alt">
|
|
52
|
+
<h2 slot="header">Heating services</h2>
|
|
53
|
+
<p>Product and services we offer for energy in your home</p>
|
|
54
|
+
<div slot="footer">Footnote</div>
|
|
55
|
+
</${tag}>`);
|
|
56
|
+
await defaultChecks(cardElement);
|
|
57
|
+
|
|
58
|
+
const shadowRoot = cardElement.shadowRoot;
|
|
59
|
+
|
|
60
|
+
const headerSelector = shadowRoot.querySelector('.header');
|
|
61
|
+
expect(headerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
62
|
+
const header = headerSelector.querySelector('slot[name="header"]');
|
|
63
|
+
expect(header.assignedElements()[0].textContent).to.equal('Heating services', 'Heading slot value matches');
|
|
64
|
+
|
|
65
|
+
const content = shadowRoot.querySelector('.content');
|
|
66
|
+
expect(shadowRoot.querySelector('.content')).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
67
|
+
const paragraph = content.querySelector('slot');
|
|
68
|
+
expect(paragraph.assignedElements()[0].textContent).to.equal('Product and services we offer for energy in your home', 'Content slot value matches');
|
|
69
|
+
|
|
70
|
+
const footerSelector = shadowRoot.querySelector('.footer');
|
|
71
|
+
expect(footerSelector).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
72
|
+
const footer = footerSelector.querySelector('slot[name="footer"]');
|
|
73
|
+
expect(footer.assignedElements()[0].textContent).to.equal('Footnote', 'Footer slot value matches');
|
|
74
|
+
|
|
75
|
+
const media = shadowRoot.querySelector('.media');
|
|
76
|
+
expect(media).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
77
|
+
const image = media.querySelector('card-image');
|
|
78
|
+
expect(image.src).to.include('tests/components/image/images/150.png', 'card image has correct value');
|
|
79
|
+
expect(image.alt).to.equal('image alt', 'card image alt has correct value');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/* @web/test-runner snapshot v1 */
|
|
2
|
+
export const snapshots = {};
|
|
3
|
+
|
|
4
|
+
snapshots["cta implements standard self"] =
|
|
5
|
+
`<div
|
|
6
|
+
aria-label="Buy a doughnut"
|
|
7
|
+
class="cta standard"
|
|
8
|
+
>
|
|
9
|
+
<span class="label-holder">
|
|
10
|
+
<slot>
|
|
11
|
+
</slot>
|
|
12
|
+
</span>
|
|
13
|
+
<cta-icon
|
|
14
|
+
class="icon"
|
|
15
|
+
name="arrow-right"
|
|
16
|
+
>
|
|
17
|
+
</cta-icon>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
/* end snapshot cta implements standard self */
|
|
21
|
+
|
|
22
|
+
snapshots["cta no icon"] =
|
|
23
|
+
`<div
|
|
24
|
+
aria-label="Click me please"
|
|
25
|
+
class="cta standard"
|
|
26
|
+
>
|
|
27
|
+
<span class="label-holder">
|
|
28
|
+
<slot>
|
|
29
|
+
</slot>
|
|
30
|
+
</span>
|
|
31
|
+
</div>
|
|
32
|
+
`;
|
|
33
|
+
/* end snapshot cta no icon */
|
|
34
|
+
|
|
35
|
+
snapshots["cta implements with no icon"] =
|
|
36
|
+
`<div
|
|
37
|
+
aria-label="Click me please"
|
|
38
|
+
class="cta standard"
|
|
39
|
+
>
|
|
40
|
+
<span class="label-holder">
|
|
41
|
+
<slot>
|
|
42
|
+
</slot>
|
|
43
|
+
</span>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
/* end snapshot cta implements with no icon */
|
|
47
|
+
|
|
48
|
+
snapshots["cta implements with loading"] =
|
|
49
|
+
`<span
|
|
50
|
+
aria-live="assertive"
|
|
51
|
+
class="sr-only"
|
|
52
|
+
role="alert"
|
|
53
|
+
>
|
|
54
|
+
Loading...
|
|
55
|
+
</span>
|
|
56
|
+
<div
|
|
57
|
+
aria-label="This is a button"
|
|
58
|
+
class="cta loading standard"
|
|
59
|
+
>
|
|
60
|
+
<span class="label-holder">
|
|
61
|
+
Loading...
|
|
62
|
+
</span>
|
|
63
|
+
<cta-icon
|
|
64
|
+
class="icon"
|
|
65
|
+
name="spinner"
|
|
66
|
+
>
|
|
67
|
+
</cta-icon>
|
|
68
|
+
</div>
|
|
69
|
+
`;
|
|
70
|
+
/* end snapshot cta implements with loading */
|
|
71
|
+
|
|
72
|
+
snapshots["cta implements with icon at start"] =
|
|
73
|
+
`<div
|
|
74
|
+
aria-label="Something something...danger zone"
|
|
75
|
+
class="cta standard"
|
|
76
|
+
>
|
|
77
|
+
<cta-icon
|
|
78
|
+
class="icon"
|
|
79
|
+
name="arrow-right"
|
|
80
|
+
>
|
|
81
|
+
</cta-icon>
|
|
82
|
+
<span class="label-holder">
|
|
83
|
+
<slot>
|
|
84
|
+
</slot>
|
|
85
|
+
</span>
|
|
86
|
+
</div>
|
|
87
|
+
`;
|
|
88
|
+
/* end snapshot cta implements with icon at start */
|
|
89
|
+
|
|
90
|
+
snapshots["cta implements with a href"] =
|
|
91
|
+
`<a
|
|
92
|
+
aria-label="This is a button"
|
|
93
|
+
class="cta standard"
|
|
94
|
+
href="https://example.com"
|
|
95
|
+
tabindex="0"
|
|
96
|
+
>
|
|
97
|
+
<span class="label-holder">
|
|
98
|
+
<slot>
|
|
99
|
+
</slot>
|
|
100
|
+
</span>
|
|
101
|
+
<cta-icon
|
|
102
|
+
class="icon"
|
|
103
|
+
name="arrow-right"
|
|
104
|
+
>
|
|
105
|
+
</cta-icon>
|
|
106
|
+
</a>
|
|
107
|
+
`;
|
|
108
|
+
/* end snapshot cta implements with a href */
|
|
109
|
+
|
|
110
|
+
snapshots["cta implements cta within an anchor element"] =
|
|
111
|
+
`<div
|
|
112
|
+
aria-label="This is a button"
|
|
113
|
+
class="cta standard"
|
|
114
|
+
tabindex="-1"
|
|
115
|
+
>
|
|
116
|
+
<span class="label-holder">
|
|
117
|
+
<slot>
|
|
118
|
+
</slot>
|
|
119
|
+
</span>
|
|
120
|
+
<cta-icon
|
|
121
|
+
class="icon"
|
|
122
|
+
name="arrow-right"
|
|
123
|
+
>
|
|
124
|
+
</cta-icon>
|
|
125
|
+
</div>
|
|
126
|
+
`;
|
|
127
|
+
/* end snapshot cta implements cta within an anchor element */
|
|
128
|
+
|
|
129
|
+
snapshots["cta implements within a form"] =
|
|
130
|
+
`<button
|
|
131
|
+
aria-label="This is a button"
|
|
132
|
+
class="cta standard"
|
|
133
|
+
tabindex="0"
|
|
134
|
+
>
|
|
135
|
+
<span class="label-holder">
|
|
136
|
+
<slot>
|
|
137
|
+
</slot>
|
|
138
|
+
</span>
|
|
139
|
+
<cta-icon
|
|
140
|
+
class="icon"
|
|
141
|
+
name="arrow-right"
|
|
142
|
+
>
|
|
143
|
+
</cta-icon>
|
|
144
|
+
</button>
|
|
145
|
+
`;
|
|
146
|
+
/* end snapshot cta implements within a form */
|
|
147
|
+
|
|
148
|
+
snapshots["cta implements with triggering button"] =
|
|
149
|
+
`<button
|
|
150
|
+
aria-label="This is a button"
|
|
151
|
+
class="cta standard"
|
|
152
|
+
tabindex="0"
|
|
153
|
+
>
|
|
154
|
+
<span class="label-holder">
|
|
155
|
+
<slot>
|
|
156
|
+
</slot>
|
|
157
|
+
</span>
|
|
158
|
+
<cta-icon
|
|
159
|
+
class="icon"
|
|
160
|
+
name="arrow-right"
|
|
161
|
+
>
|
|
162
|
+
</cta-icon>
|
|
163
|
+
</button>
|
|
164
|
+
`;
|
|
165
|
+
/* end snapshot cta implements with triggering button */
|
|
166
|
+
|
|
167
|
+
snapshots["cta implements loading as a button"] =
|
|
168
|
+
`<span
|
|
169
|
+
aria-live="assertive"
|
|
170
|
+
class="sr-only"
|
|
171
|
+
role="alert"
|
|
172
|
+
>
|
|
173
|
+
Loading...
|
|
174
|
+
</span>
|
|
175
|
+
<button
|
|
176
|
+
aria-label="This is a button"
|
|
177
|
+
class="cta loading standard"
|
|
178
|
+
disabled=""
|
|
179
|
+
tabindex="0"
|
|
180
|
+
>
|
|
181
|
+
<span class="label-holder">
|
|
182
|
+
Loading...
|
|
183
|
+
</span>
|
|
184
|
+
<cta-icon
|
|
185
|
+
class="icon"
|
|
186
|
+
name="spinner"
|
|
187
|
+
>
|
|
188
|
+
</cta-icon>
|
|
189
|
+
</button>
|
|
190
|
+
`;
|
|
191
|
+
/* end snapshot cta implements loading as a button */
|
|
192
|
+
|
|
193
|
+
snapshots["cta implements with disabled"] =
|
|
194
|
+
`<div
|
|
195
|
+
aria-label="This is a button"
|
|
196
|
+
class="cta disabled standard"
|
|
197
|
+
>
|
|
198
|
+
<span class="label-holder">
|
|
199
|
+
<slot>
|
|
200
|
+
</slot>
|
|
201
|
+
</span>
|
|
202
|
+
<cta-icon
|
|
203
|
+
class="icon"
|
|
204
|
+
name="arrow-right"
|
|
205
|
+
>
|
|
206
|
+
</cta-icon>
|
|
207
|
+
</div>
|
|
208
|
+
`;
|
|
209
|
+
/* end snapshot cta implements with disabled */
|
|
210
|
+
|
|
211
|
+
snapshots["cta implements template `submit`"] =
|
|
212
|
+
`<div
|
|
213
|
+
aria-label="This is a button"
|
|
214
|
+
class="cta submit"
|
|
215
|
+
>
|
|
216
|
+
<span class="label-holder">
|
|
217
|
+
<slot>
|
|
218
|
+
</slot>
|
|
219
|
+
</span>
|
|
220
|
+
<cta-icon
|
|
221
|
+
class="icon"
|
|
222
|
+
name="arrow-right"
|
|
223
|
+
>
|
|
224
|
+
</cta-icon>
|
|
225
|
+
</div>
|
|
226
|
+
`;
|
|
227
|
+
/* end snapshot cta implements template `submit` */
|
|
228
|
+
|
|
229
|
+
snapshots["cta implements template `reset`"] =
|
|
230
|
+
`<div
|
|
231
|
+
aria-label="This is a button"
|
|
232
|
+
class="cta reset"
|
|
233
|
+
>
|
|
234
|
+
<span class="label-holder">
|
|
235
|
+
<slot>
|
|
236
|
+
</slot>
|
|
237
|
+
</span>
|
|
238
|
+
<cta-icon
|
|
239
|
+
class="icon"
|
|
240
|
+
name="arrow-right"
|
|
241
|
+
>
|
|
242
|
+
</cta-icon>
|
|
243
|
+
</div>
|
|
244
|
+
`;
|
|
245
|
+
/* end snapshot cta implements template `reset` */
|
|
246
|
+
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
|
|
3
|
+
import { defaultChecks } from '../../helpers';
|
|
4
|
+
import { Cta } from '@muonic/muon/components/cta';
|
|
5
|
+
|
|
6
|
+
const tagName = defineCE(Cta);
|
|
7
|
+
const tag = unsafeStatic(tagName);
|
|
8
|
+
|
|
9
|
+
describe('cta', () => {
|
|
10
|
+
it('implements standard self', async () => {
|
|
11
|
+
const el = await fixture(html`<${tag}>Buy a doughnut</${tag}>`);
|
|
12
|
+
|
|
13
|
+
await defaultChecks(el);
|
|
14
|
+
|
|
15
|
+
const shadowRoot = el.shadowRoot;
|
|
16
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
17
|
+
const icon = cta.querySelector('.icon');
|
|
18
|
+
const label = cta.querySelector('.label-holder');
|
|
19
|
+
|
|
20
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
21
|
+
expect(el.icon).to.equal('arrow-right', '`icon` property has default value `arrow-right`');
|
|
22
|
+
expect(el.loading).to.equal(false, '`loading` property has default value `false`');
|
|
23
|
+
expect(el.loadingMessage).to.equal('Loading...', '`loadingMessage` property has default value `Loading...`');
|
|
24
|
+
expect(el.href).to.equal(undefined, '`href` attribute has no default value');
|
|
25
|
+
expect(el._iconPosition).to.equal('end', '`_iconPosition` attribute has default value `end`');
|
|
26
|
+
expect(el._isButton).to.equal(undefined, '`_isButton` attribute has no default value');
|
|
27
|
+
expect(el.getAttribute('role')).to.equal('button', 'has the role of button');
|
|
28
|
+
expect(el.getAttribute('tabindex')).to.equal('0', 'has a tab index');
|
|
29
|
+
expect(el.getAttribute('aria-disabled')).to.equal(null, '`disabled aria` has not been set');
|
|
30
|
+
expect(cta.nodeName).to.equal('DIV', 'parent element inside shadow should be `div`');
|
|
31
|
+
expect(cta.getAttribute('aria-label')).to.equal('Buy a doughnut', '`aria-label` has same value as anonymous slot');
|
|
32
|
+
expect(cta.getAttribute('tabindex')).to.equal(null, 'has no tab index');
|
|
33
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
34
|
+
expect(cta.children[0].nodeName).to.equal('SPAN', 'first element within cta is span');
|
|
35
|
+
expect(cta.children[1].nodeName).to.equal('CTA-ICON', 'second element within cta is icon');
|
|
36
|
+
expect(icon.nodeName).to.equal('CTA-ICON', 'Scoped CTA component');
|
|
37
|
+
expect(icon.name).to.equal('arrow-right', 'Scoped icon has name value `arrow-right`');
|
|
38
|
+
expect(label.nodeName).to.equal('SPAN', 'span label holder exists');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('implements with no icon', async () => {
|
|
42
|
+
const el = await fixture(html`<${tag} icon="">Click me please</${tag}>`);
|
|
43
|
+
|
|
44
|
+
await defaultChecks(el);
|
|
45
|
+
|
|
46
|
+
const shadowRoot = el.shadowRoot;
|
|
47
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
48
|
+
const icon = cta.querySelector('.icon');
|
|
49
|
+
|
|
50
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
51
|
+
expect(el.icon).to.equal('', '`icon` property has no value');
|
|
52
|
+
expect(icon).to.equal(null, 'no icon added');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('implements with loading', async () => {
|
|
56
|
+
const el = await fixture(html`<${tag} loading>This is a button</${tag}>`);
|
|
57
|
+
|
|
58
|
+
await defaultChecks(el);
|
|
59
|
+
|
|
60
|
+
const shadowRoot = el.shadowRoot;
|
|
61
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
62
|
+
const icon = cta.querySelector('.icon');
|
|
63
|
+
const srLoading = shadowRoot.querySelector('[role="alert"]');
|
|
64
|
+
|
|
65
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
66
|
+
expect(el.icon).to.equal('arrow-right', '`icon` has default property value');
|
|
67
|
+
expect(icon.name).to.equal('spinner', 'icon has loading icon of `spinner`');
|
|
68
|
+
expect(srLoading.innerText).to.equal('Loading...', 'Screen reader only message for loading');
|
|
69
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('implements with disabled', async () => {
|
|
73
|
+
const el = await fixture(html`<${tag} disabled>This is a button</${tag}>`);
|
|
74
|
+
|
|
75
|
+
await defaultChecks(el);
|
|
76
|
+
|
|
77
|
+
const shadowRoot = el.shadowRoot;
|
|
78
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
79
|
+
|
|
80
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
81
|
+
expect(el.icon).to.equal('arrow-right', '`icon` has default property value');
|
|
82
|
+
expect(el.disabled).to.equal(true, '`disabled` has been set to true');
|
|
83
|
+
expect(el.getAttribute('aria-disabled')).to.equal('true', '`disabled aria` has been set to true');
|
|
84
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('implements with icon at start', async () => {
|
|
88
|
+
const el = await fixture(html`<${tag}>Something something...danger zone</${tag}>`);
|
|
89
|
+
|
|
90
|
+
el._iconPosition = 'start';
|
|
91
|
+
|
|
92
|
+
await defaultChecks(el);
|
|
93
|
+
|
|
94
|
+
const shadowRoot = el.shadowRoot;
|
|
95
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
96
|
+
|
|
97
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
98
|
+
expect(cta.children[0].nodeName).to.equal('CTA-ICON', 'first element within cta is icon');
|
|
99
|
+
expect(cta.children[1].nodeName).to.equal('SPAN', 'second element within cta is span');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('implements with a href', async () => {
|
|
103
|
+
const el = await fixture(html`<${tag} href="https://example.com">This is a button</${tag}>`);
|
|
104
|
+
|
|
105
|
+
await defaultChecks(el);
|
|
106
|
+
|
|
107
|
+
const shadowRoot = el.shadowRoot;
|
|
108
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
109
|
+
|
|
110
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
111
|
+
expect(cta.nodeName).to.equal('A', 'cta is an anchor element');
|
|
112
|
+
expect(cta.href).to.equal('https://example.com/', 'cta has the href');
|
|
113
|
+
expect(cta.getAttribute('tabindex')).to.equal('0', 'has tab index');
|
|
114
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('implements cta within an anchor element', async () => {
|
|
118
|
+
const parentTemplate = await fixture(html`<a href="https://example.com"><${tag}>This is a button</${tag}></a>`);
|
|
119
|
+
const el = parentTemplate.querySelector('test-0'); // @TODO: Find a way to get this from the tag
|
|
120
|
+
|
|
121
|
+
await defaultChecks(el);
|
|
122
|
+
|
|
123
|
+
const shadowRoot = el.shadowRoot;
|
|
124
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
125
|
+
|
|
126
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
127
|
+
expect(cta.nodeName).to.equal('DIV', 'cta is a `div` element');
|
|
128
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
129
|
+
expect(cta.getAttribute('tabindex')).to.equal('-1', 'has tab index');
|
|
130
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('implements within a form', async () => {
|
|
134
|
+
const parentTemplate = await fixture(html`<form><${tag}>This is a button</${tag}></form>`);
|
|
135
|
+
const el = parentTemplate.querySelector('test-0'); // @TODO: Find a way to get this from the tag
|
|
136
|
+
|
|
137
|
+
await defaultChecks(el);
|
|
138
|
+
|
|
139
|
+
const shadowRoot = el.shadowRoot;
|
|
140
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
141
|
+
|
|
142
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
143
|
+
expect(el.getAttribute('role')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
144
|
+
expect(el.getAttribute('tabindex')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
145
|
+
expect(cta.nodeName).to.equal('BUTTON', 'cta is a `div` element');
|
|
146
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
147
|
+
expect(cta.getAttribute('tabindex')).to.equal('0', 'has tab index');
|
|
148
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('implements with triggering button', async () => {
|
|
152
|
+
// this is to force it to act like it is in a form (aka you need a native button element)
|
|
153
|
+
const el = await fixture(html`<${tag}>This is a button</${tag}>`);
|
|
154
|
+
el._isButton = true;
|
|
155
|
+
await defaultChecks(el);
|
|
156
|
+
|
|
157
|
+
const shadowRoot = el.shadowRoot;
|
|
158
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
159
|
+
|
|
160
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
161
|
+
expect(el.getAttribute('role')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
162
|
+
expect(el.getAttribute('tabindex')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
163
|
+
expect(cta.nodeName).to.equal('BUTTON', 'cta is a `div` element');
|
|
164
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
165
|
+
expect(cta.getAttribute('tabindex')).to.equal('0', 'has tab index');
|
|
166
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is not disabled');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('implements loading as a button', async () => {
|
|
170
|
+
// this is to force it to act like it is in a form (aka you need a native button element)
|
|
171
|
+
const el = await fixture(html`<${tag} loading>This is a button</${tag}>`);
|
|
172
|
+
el._isButton = true;
|
|
173
|
+
await defaultChecks(el);
|
|
174
|
+
|
|
175
|
+
const shadowRoot = el.shadowRoot;
|
|
176
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
177
|
+
|
|
178
|
+
expect(el.type).to.equal('standard', '`type` property has default value `standard`');
|
|
179
|
+
expect(el.getAttribute('role')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
180
|
+
expect(el.getAttribute('tabindex')).to.not.exist; // eslint-disable-line no-unused-expressions
|
|
181
|
+
expect(cta.nodeName).to.equal('BUTTON', 'cta is a `button` element');
|
|
182
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
183
|
+
expect(cta.getAttribute('tabindex')).to.equal('0', 'has tab index');
|
|
184
|
+
expect(cta.getAttribute('disabled')).to.equal('', 'cta is disabled');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('implements template `submit`', async () => {
|
|
188
|
+
// this is to force it to act like it is in a form (aka you need a native button element)
|
|
189
|
+
const el = await fixture(html`<${tag} type="submit">This is a button</${tag}>`);
|
|
190
|
+
await defaultChecks(el);
|
|
191
|
+
|
|
192
|
+
const shadowRoot = el.shadowRoot;
|
|
193
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
194
|
+
|
|
195
|
+
expect(el.type).to.equal('submit', '`type` property has default value `submit`');
|
|
196
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
197
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is disabled');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('implements template `reset`', async () => {
|
|
201
|
+
// this is to force it to act like it is in a form (aka you need a native button element)
|
|
202
|
+
const el = await fixture(html`<${tag} type="reset">This is a button</${tag}>`);
|
|
203
|
+
await defaultChecks(el);
|
|
204
|
+
|
|
205
|
+
const shadowRoot = el.shadowRoot;
|
|
206
|
+
const cta = shadowRoot.querySelector('.cta');
|
|
207
|
+
|
|
208
|
+
expect(el.type).to.equal('reset', '`type` property has default value `reset`');
|
|
209
|
+
expect(cta.href).to.equal(false, 'cta has NO href');
|
|
210
|
+
expect(cta.getAttribute('disabled')).to.equal(null, 'cta is disabled');
|
|
211
|
+
});
|
|
212
|
+
});
|