@govtechsg/sgds-web-component 0.0.7 → 0.0.10
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/.github/workflows/publish-latest.yml +22 -0
- package/.github/workflows/publish-pr.yml +28 -0
- package/.husky/commit-msg +4 -0
- package/.husky/prepare-commit-msg +8 -0
- package/.storybook/main.js +16 -0
- package/.storybook/preview-head.html +11 -0
- package/.storybook/preview.js +9 -0
- package/.vscode/settings.json +7 -0
- package/CONTRIBUTING.md +56 -0
- package/LICENSE +20 -0
- package/amplify.yml +22 -0
- package/commitlint.config.js +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/button-element.scss.html +112 -0
- package/coverage/lcov-report/button-element.ts.html +145 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +116 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +32 -0
- package/index.html +430 -0
- package/{Button → lib/Button}/index.d.ts +0 -0
- package/{Button → lib/Button}/index.js +304 -39
- package/lib/Button/index.js.map +1 -0
- package/{Button → lib/Button}/package.json +0 -0
- package/lib/Button/sgds-button.d.ts +48 -0
- package/lib/Card/index.d.ts +1 -0
- package/lib/Card/index.js +6150 -0
- package/lib/Card/index.js.map +1 -0
- package/lib/Card/package.json +7 -0
- package/lib/Card/sgds-action-card.d.ts +20 -0
- package/lib/Checkbox/index.d.ts +1 -0
- package/lib/Checkbox/index.js +6366 -0
- package/lib/Checkbox/index.js.map +1 -0
- package/lib/Checkbox/package.json +7 -0
- package/lib/Checkbox/sgds-checkbox.d.ts +36 -0
- package/lib/Dropdown/index.d.ts +3 -0
- package/{Mainnav → lib/Dropdown}/index.js +2786 -9258
- package/lib/Dropdown/index.js.map +1 -0
- package/lib/Dropdown/package.json +7 -0
- package/lib/Dropdown/sgds-dropdown-item.d.ts +7 -0
- package/lib/Dropdown/sgds-dropdown.d.ts +7 -0
- package/{Footer → lib/Footer}/index.d.ts +0 -0
- package/{Footer → lib/Footer}/index.js +111 -95
- package/lib/Footer/index.js.map +1 -0
- package/{Footer → lib/Footer}/package.json +0 -0
- package/{Footer → lib/Footer}/sgds-footer.d.ts +2 -2
- package/lib/Input/index.d.ts +1 -0
- package/lib/Input/index.js +6656 -0
- package/lib/Input/index.js.map +1 -0
- package/lib/Input/package.json +7 -0
- package/lib/Input/sgds-input.d.ts +42 -0
- package/{Mainnav → lib/Mainnav}/index.d.ts +1 -0
- package/{index.js → lib/Mainnav/index.js} +3876 -23415
- package/lib/Mainnav/index.js.map +1 -0
- package/{Mainnav → lib/Mainnav}/package.json +0 -0
- package/lib/Mainnav/sgds-mainnav-dropdown.d.ts +5 -0
- package/lib/Mainnav/sgds-mainnav-item.d.ts +4 -0
- package/{Mainnav → lib/Mainnav}/sgds-mainnav.d.ts +3 -2
- package/{Masthead → lib/Masthead}/index.d.ts +0 -0
- package/{Masthead → lib/Masthead}/index.js +140 -114
- package/lib/Masthead/index.js.map +1 -0
- package/{Masthead → lib/Masthead}/package.json +0 -0
- package/{Masthead → lib/Masthead}/sgds-masthead.d.ts +1 -1
- package/lib/Modal/index.d.ts +1 -0
- package/lib/Modal/index.js +6432 -0
- package/lib/Modal/index.js.map +1 -0
- package/lib/Modal/package.json +7 -0
- package/lib/Modal/sgds-modal.d.ts +28 -0
- package/lib/QuantityToggle/index.d.ts +1 -0
- package/lib/QuantityToggle/index.js +7049 -0
- package/lib/QuantityToggle/index.js.map +1 -0
- package/lib/QuantityToggle/package.json +7 -0
- package/lib/QuantityToggle/sgds-quantitytoggle.d.ts +30 -0
- package/lib/Radio/index.d.ts +2 -0
- package/lib/Radio/index.js +12607 -0
- package/lib/Radio/index.js.map +1 -0
- package/lib/Radio/package.json +7 -0
- package/lib/Radio/sgds-radio.d.ts +31 -0
- package/lib/Radio/sgds-radiogroup.d.ts +41 -0
- package/{Sidenav → lib/Sidenav}/index.d.ts +0 -0
- package/{Sidenav → lib/Sidenav}/index.js +2266 -2171
- package/lib/Sidenav/index.js.map +1 -0
- package/{Sidenav → lib/Sidenav}/package.json +0 -0
- package/{Sidenav → lib/Sidenav}/sgds-sidenav-item.d.ts +2 -1
- package/lib/Sidenav/sgds-sidenav-link.d.ts +4 -0
- package/{Sidenav → lib/Sidenav}/sgds-sidenav.d.ts +1 -1
- package/lib/Tab/index.d.ts +3 -0
- package/lib/Tab/index.js +13557 -0
- package/lib/Tab/index.js.map +1 -0
- package/lib/Tab/package.json +7 -0
- package/lib/Tab/sgds-tab.d.ts +26 -0
- package/lib/Tab/sgds-tabgroup.d.ts +47 -0
- package/lib/Tab/sgds-tabpanel.d.ts +25 -0
- package/lib/Textarea/index.d.ts +1 -0
- package/lib/Textarea/index.js +6696 -0
- package/lib/Textarea/index.js.map +1 -0
- package/lib/Textarea/package.json +7 -0
- package/lib/Textarea/sgds-textarea.d.ts +53 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +134580 -0
- package/lib/index.js.map +1 -0
- package/lib/umd/index.js +134587 -0
- package/lib/umd/index.js.map +1 -0
- package/lib/utils/animate.d.ts +10 -0
- package/lib/utils/animation-registry.d.ts +18 -0
- package/{utils → lib/utils}/breakpoints.d.ts +0 -0
- package/lib/utils/card-element.d.ts +11 -0
- package/lib/utils/defaultvalue.d.ts +2 -0
- package/lib/utils/dropdown-element.d.ts +37 -0
- package/lib/utils/event.d.ts +2 -0
- package/lib/utils/form.d.ts +38 -0
- package/{utils → lib/utils}/generateId.d.ts +0 -0
- package/lib/utils/link-element.d.ts +7 -0
- package/lib/utils/mergeDeep.d.ts +2 -0
- package/lib/utils/modal.d.ts +12 -0
- package/lib/utils/object.d.ts +2 -0
- package/lib/utils/offset.d.ts +4 -0
- package/lib/utils/scroll.d.ts +13 -0
- package/{utils → lib/utils}/sgds-element.d.ts +0 -0
- package/lib/utils/slot.d.ts +22 -0
- package/lib/utils/tabbable.d.ts +8 -0
- package/lib/utils/watch.d.ts +14 -0
- package/mocks/dropdown.d.ts +4 -0
- package/mocks/dropdown.ts +27 -0
- package/mocks/link.d.ts +3 -0
- package/mocks/link.ts +6 -0
- package/package.json +65 -10
- package/rollup.config.js +73 -0
- package/rollup.test.config.js +42 -0
- package/scripts/buildUtils.js +30 -0
- package/scripts/frankBuild.js +49 -0
- package/src/Button/index.ts +1 -0
- package/src/Button/sgds-button.scss +28 -0
- package/src/Button/sgds-button.ts +153 -0
- package/src/Card/index.ts +1 -0
- package/src/Card/sgds-action-card.scss +27 -0
- package/src/Card/sgds-action-card.ts +115 -0
- package/src/Checkbox/index.ts +1 -0
- package/src/Checkbox/sgds-checkbox.scss +4 -0
- package/src/Checkbox/sgds-checkbox.ts +149 -0
- package/src/Dropdown/index.ts +3 -0
- package/src/Dropdown/sgds-dropdown-item.ts +39 -0
- package/src/Dropdown/sgds-dropdown.scss +5 -0
- package/src/Dropdown/sgds-dropdown.ts +54 -0
- package/src/Footer/index.ts +3 -0
- package/src/Footer/sgds-footer.scss +5 -0
- package/src/Footer/sgds-footer.ts +121 -0
- package/src/Input/index.ts +1 -0
- package/src/Input/sgds-input.scss +20 -0
- package/src/Input/sgds-input.ts +178 -0
- package/src/Mainnav/index.ts +4 -0
- package/src/Mainnav/sgds-mainnav-dropdown.scss +13 -0
- package/src/Mainnav/sgds-mainnav-dropdown.ts +45 -0
- package/src/Mainnav/sgds-mainnav-item.scss +24 -0
- package/src/Mainnav/sgds-mainnav-item.ts +8 -0
- package/src/Mainnav/sgds-mainnav.scss +39 -0
- package/src/Mainnav/sgds-mainnav.ts +183 -0
- package/src/Masthead/index.ts +1 -0
- package/src/Masthead/sgds-masthead.scss +217 -0
- package/src/Masthead/sgds-masthead.ts +189 -0
- package/src/Modal/index.ts +1 -0
- package/src/Modal/sgds-modal.scss +128 -0
- package/src/Modal/sgds-modal.ts +309 -0
- package/src/QuantityToggle/index.ts +1 -0
- package/src/QuantityToggle/sgds-quantitytoggle.scss +10 -0
- package/src/QuantityToggle/sgds-quantitytoggle.ts +130 -0
- package/src/Radio/index.ts +2 -0
- package/src/Radio/sgds-radio.scss +5 -0
- package/src/Radio/sgds-radio.ts +120 -0
- package/src/Radio/sgds-radiogroup.scss +22 -0
- package/src/Radio/sgds-radiogroup.ts +221 -0
- package/src/Sidenav/index.ts +4 -0
- package/src/Sidenav/sgds-sidenav-item.scss +73 -0
- package/src/Sidenav/sgds-sidenav-item.ts +145 -0
- package/src/Sidenav/sgds-sidenav-link.scss +25 -0
- package/src/Sidenav/sgds-sidenav-link.ts +8 -0
- package/src/Sidenav/sgds-sidenav.scss +6 -0
- package/src/Sidenav/sgds-sidenav.ts +33 -0
- package/src/Tab/index.ts +3 -0
- package/src/Tab/sgds-tab.scss +84 -0
- package/src/Tab/sgds-tab.ts +87 -0
- package/src/Tab/sgds-tabgroup.scss +198 -0
- package/src/Tab/sgds-tabgroup.ts +295 -0
- package/src/Tab/sgds-tabpanel.scss +12 -0
- package/src/Tab/sgds-tabpanel.ts +55 -0
- package/src/Textarea/index.ts +1 -0
- package/src/Textarea/sgds-textarea.scss +23 -0
- package/src/Textarea/sgds-textarea.ts +201 -0
- package/src/index.ts +16 -0
- package/src/utils/animate.ts +69 -0
- package/src/utils/animation-registry.ts +71 -0
- package/src/utils/base.scss +14 -0
- package/src/utils/breakpoints.ts +5 -0
- package/src/utils/card-element.ts +42 -0
- package/src/utils/components.style.scss +531 -0
- package/src/utils/defaultvalue.ts +51 -0
- package/src/utils/dropdown-element.ts +244 -0
- package/src/utils/event.ts +13 -0
- package/src/utils/form.ts +183 -0
- package/src/utils/generateId.ts +4 -0
- package/src/utils/link-element.ts +34 -0
- package/src/utils/mergeDeep.ts +22 -0
- package/src/utils/modal.ts +64 -0
- package/src/utils/object.ts +2 -0
- package/src/utils/offset.ts +6 -0
- package/src/utils/scroll.ts +57 -0
- package/src/utils/sgds-element.ts +18 -0
- package/src/utils/slot.ts +102 -0
- package/src/utils/tabbable.ts +81 -0
- package/src/utils/watch.ts +62 -0
- package/stories/ActionCard.stories.mdx +199 -0
- package/stories/Button.stories.mdx +194 -0
- package/stories/Checkbox.stories.mdx +196 -0
- package/stories/Dropdown.stories.mdx +152 -0
- package/stories/Footer.stories.mdx +261 -0
- package/stories/Input.stories.mdx +236 -0
- package/stories/MainNav.stories.mdx +169 -0
- package/stories/Masthead.stories.mdx +112 -0
- package/stories/Modal.stories.mdx +103 -0
- package/stories/QuantityToggle.stories.mdx +97 -0
- package/stories/Radio.stories.mdx +262 -0
- package/stories/Sample.stories.js +29 -0
- package/stories/Sample.stories.mdx +33 -0
- package/stories/SideNav.stories.mdx +245 -0
- package/stories/common.js +185 -0
- package/stories/textarea.stories.mdx +253 -0
- package/test/button.element.test.ts +185 -0
- package/test/checkbox.test.ts +240 -0
- package/test/dropdown.test.ts +637 -0
- package/test/footer.test.ts +181 -0
- package/test/generateId.test.ts +18 -0
- package/test/input.element.test.ts +316 -0
- package/test/link-element.test.ts +38 -0
- package/test/mainnav.test.ts +313 -0
- package/test/masthead.test.ts +116 -0
- package/test/modal.test.ts +149 -0
- package/test/quantitytoggle.test.ts +76 -0
- package/test/radio.test.ts +310 -0
- package/test/selectable-card.test.ts +159 -0
- package/test/sidenav.test.ts +390 -0
- package/test/tab.test.ts +76 -0
- package/test/textarea.test.ts +126 -0
- package/tsconfig.json +26 -0
- package/tsconfig.test.json +24 -0
- package/typings/scss.d.ts +5 -0
- package/web-dev-server.config.mjs +7 -0
- package/web-test-runner.config.mjs +47 -0
- package/Button/index.js.map +0 -1
- package/Button/sgds-button.d.ts +0 -23
- package/Footer/index.js.map +0 -1
- package/Mainnav/index.js.map +0 -1
- package/Mainnav/sgds-mainnav-item.d.ts +0 -7
- package/Masthead/index.js.map +0 -1
- package/Sidenav/index.js.map +0 -1
- package/Sidenav/sgds-sidenav-link.d.ts +0 -7
- package/index.d.ts +0 -5
- package/index.js.map +0 -1
- package/umd/index.js +0 -52092
- package/umd/index.js.map +0 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { SgdsRadio, SgdsRadioGroup } from "../src/Radio";
|
|
2
|
+
import "../src/Radio";
|
|
3
|
+
import "../src/Button";
|
|
4
|
+
import {
|
|
5
|
+
fixture,
|
|
6
|
+
assert,
|
|
7
|
+
expect,
|
|
8
|
+
waitUntil,
|
|
9
|
+
elementUpdated,
|
|
10
|
+
aTimeout,
|
|
11
|
+
fixtureCleanup,
|
|
12
|
+
triggerFocusFor,
|
|
13
|
+
} from "@open-wc/testing";
|
|
14
|
+
import { html } from "lit";
|
|
15
|
+
import sinon from "sinon";
|
|
16
|
+
import { SgdsButton } from "../src/Button";
|
|
17
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
18
|
+
|
|
19
|
+
describe("<sgds-radio>", () => {
|
|
20
|
+
afterEach(() => fixtureCleanup());
|
|
21
|
+
it("is defined", () => {
|
|
22
|
+
const el = document.createElement("sgds-radio");
|
|
23
|
+
assert.instanceOf(el, SgdsRadio);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("by default, tabindex='-1'", async () => {
|
|
27
|
+
const el = await fixture(html`<sgds-radio></sgds-radio>`);
|
|
28
|
+
expect(el).to.have.attribute("tabindex", "-1");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("when isInline prop is passed, radio class should have class .form-check-inline", async () => {
|
|
32
|
+
const el = await fixture(html`<sgds-radio isInline></sgds-radio>`);
|
|
33
|
+
const radio = el.shadowRoot?.querySelector("div");
|
|
34
|
+
expect(radio?.classList.value).to.contain("form-check-inline");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("should be able to pass in value to attributes(id/for pair)", async () => {
|
|
38
|
+
const el = await fixture(
|
|
39
|
+
html`<sgds-radio radioId="radio-123"></sgds-radio>`
|
|
40
|
+
);
|
|
41
|
+
const input = el.shadowRoot?.querySelector("input");
|
|
42
|
+
expect(input).to.have.attribute("id", "radio-123");
|
|
43
|
+
const label = el.shadowRoot?.querySelector("label");
|
|
44
|
+
expect(label).to.have.attribute("for", "radio-123");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should be disabled with the disabled attribute & aria-disabled to be true", async () => {
|
|
48
|
+
const el = await fixture(html`<sgds-radio disabled></sgds-radio>`);
|
|
49
|
+
const radio = el.shadowRoot?.querySelector("input");
|
|
50
|
+
expect(radio?.disabled).to.be.true;
|
|
51
|
+
expect(radio).to.have.attribute("aria-disabled", "true");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should render aria-label attribute value", async () => {
|
|
55
|
+
const el = await fixture(html`<sgds-radio ariaLabel="label"></sgds-radio>`);
|
|
56
|
+
const radio = el.shadowRoot?.querySelector("label");
|
|
57
|
+
expect(radio).to.have.attribute("aria-label", "label");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should be able to pass in value to value attribute", async () => {
|
|
61
|
+
const el = await fixture(html`<sgds-radio value="3"></sgds-radio>`);
|
|
62
|
+
const radio = el.shadowRoot?.querySelector("input");
|
|
63
|
+
expect(radio).to.have.attribute("value", "3");
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe("<sgds-radiogroup>", () => {
|
|
68
|
+
it("is defined", () => {
|
|
69
|
+
const el = document.createElement("sgds-radiogroup");
|
|
70
|
+
assert.instanceOf(el, SgdsRadioGroup);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should render the name attribute when passed", async () => {
|
|
74
|
+
const el = await fixture(
|
|
75
|
+
html`<sgds-radiogroup name="option"></sgds-radiogroup>`
|
|
76
|
+
);
|
|
77
|
+
const fieldset = el.shadowRoot?.querySelector("fieldset");
|
|
78
|
+
expect(fieldset).to.have.attribute("name", "option");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("radio2 should have aria-checked to be true when checked", async () => {
|
|
82
|
+
const el = await fixture(
|
|
83
|
+
html`<sgds-radiogroup name="option"
|
|
84
|
+
><sgds-radio id="radio1" value="1">one</sgds-radio
|
|
85
|
+
><sgds-radio id="radio2" value="2">two</sgds-radio></sgds-radiogroup
|
|
86
|
+
>`
|
|
87
|
+
);
|
|
88
|
+
const radio1 = <SgdsRadio>el.querySelector("sgds-radio#radio1");
|
|
89
|
+
const radio2 = <SgdsRadio>el.querySelector("sgds-radio#radio2");
|
|
90
|
+
expect(radio1.checked).to.be.false;
|
|
91
|
+
expect(radio2.checked).to.be.false;
|
|
92
|
+
expect(radio1).to.have.attribute("aria-checked", "false");
|
|
93
|
+
expect(radio2).to.have.attribute("aria-checked", "false");
|
|
94
|
+
|
|
95
|
+
radio2.click();
|
|
96
|
+
await Promise.all([radio1.updateComplete, radio2.updateComplete]);
|
|
97
|
+
|
|
98
|
+
expect(radio1.checked).to.be.false;
|
|
99
|
+
expect(radio2.checked).to.be.true;
|
|
100
|
+
expect(radio2).to.have.attribute("aria-checked", "true");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("radiogroup should emit sgds-change event when one of the radio is clicked", async () => {
|
|
104
|
+
const el = await fixture(
|
|
105
|
+
html`<sgds-radiogroup name="option">
|
|
106
|
+
<sgds-radio id="radio2" value="2">two</sgds-radio></sgds-radiogroup
|
|
107
|
+
>`
|
|
108
|
+
);
|
|
109
|
+
const toggleHandler = sinon.spy();
|
|
110
|
+
el.addEventListener("sgds-change", toggleHandler);
|
|
111
|
+
const radio2 = <SgdsRadio>el.querySelector("sgds-radio#radio2");
|
|
112
|
+
radio2.click();
|
|
113
|
+
await Promise.all([elementUpdated(el)]);
|
|
114
|
+
expect(toggleHandler).to.have.been.calledOnce;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("radiogroup should update and reflect the value for the checked radio", async () => {
|
|
118
|
+
const el = await fixture<SgdsRadioGroup>(
|
|
119
|
+
html`<sgds-radiogroup id="radiogroup">
|
|
120
|
+
<sgds-radio id="radio2" value="2">two</sgds-radio>
|
|
121
|
+
</sgds-radiogroup>`
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(el).to.have.attribute("value", undefined);
|
|
125
|
+
|
|
126
|
+
const radio = el.querySelector("sgds-radio");
|
|
127
|
+
radio?.click();
|
|
128
|
+
await el.updateComplete;
|
|
129
|
+
expect(el).to.have.attribute("value", "2");
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should be invalid state on form submission with required passed in", async () => {
|
|
133
|
+
const el = await fixture<HTMLFormElement>(
|
|
134
|
+
html`<form>
|
|
135
|
+
<sgds-radiogroup id="radiogroup" required>
|
|
136
|
+
<sgds-radio id="radio2" value="2">two</sgds-radio>
|
|
137
|
+
</sgds-radiogroup>
|
|
138
|
+
<sgds-button type="submit">Submit</sgds-button>
|
|
139
|
+
</form>`
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const button = <SgdsButton>el.querySelector("sgds-button");
|
|
143
|
+
button?.click();
|
|
144
|
+
await el.updateComplete;
|
|
145
|
+
expect(el.reportValidity()).to.be.false;
|
|
146
|
+
const radioGroup = <SgdsRadioGroup>el.querySelector("sgds-radiogroup");
|
|
147
|
+
expect(radioGroup.invalid).to.be.true;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("upon validation, it should have invalid feedback with text 'default feedback' by default, and also able to render other text when specified", async () => {
|
|
151
|
+
const el = await fixture<SgdsRadioGroup>(
|
|
152
|
+
html`
|
|
153
|
+
<sgds-radiogroup id="radiogroup" required>
|
|
154
|
+
<sgds-radio id="radio2" value="2">two</sgds-radio>
|
|
155
|
+
</sgds-radiogroup>
|
|
156
|
+
`
|
|
157
|
+
);
|
|
158
|
+
const invalidFeedback = el.shadowRoot?.querySelector(
|
|
159
|
+
"div.invalid-feedback"
|
|
160
|
+
);
|
|
161
|
+
expect(invalidFeedback?.textContent).to.contain("default feedback");
|
|
162
|
+
el.setAttribute("invalidFeedback", "Fill up this field.");
|
|
163
|
+
await elementUpdated(el);
|
|
164
|
+
expect(invalidFeedback?.textContent).to.contain("Fill up this field.");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("by default, first radio is tabindex 0", async () => {
|
|
168
|
+
const el = await fixture<SgdsRadioGroup>(html`<sgds-radiogroup>
|
|
169
|
+
<sgds-radio value="1">one</sgds-radio>
|
|
170
|
+
<sgds-radio value="2">two</sgds-radio>
|
|
171
|
+
<sgds-radio value="3">three</sgds-radio>
|
|
172
|
+
</sgds-radiogroup>`);
|
|
173
|
+
|
|
174
|
+
expect(el.querySelectorAll("sgds-radio")[0]).to.have.attribute(
|
|
175
|
+
"tabindex",
|
|
176
|
+
"0"
|
|
177
|
+
);
|
|
178
|
+
expect(el.querySelectorAll("sgds-radio")[1]).to.have.attribute(
|
|
179
|
+
"tabindex",
|
|
180
|
+
"-1"
|
|
181
|
+
);
|
|
182
|
+
expect(el.querySelectorAll("sgds-radio")[2]).to.have.attribute(
|
|
183
|
+
"tabindex",
|
|
184
|
+
"-1"
|
|
185
|
+
);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("should toggle tabindex 0 for checked radio & tabindex -1 when unchecked upon clicking", async () => {
|
|
189
|
+
const el = await fixture<SgdsRadioGroup>(html`<sgds-radiogroup>
|
|
190
|
+
<sgds-radio value="1">one</sgds-radio>
|
|
191
|
+
<sgds-radio value="2">two</sgds-radio>
|
|
192
|
+
<sgds-radio value="3">three</sgds-radio>
|
|
193
|
+
</sgds-radiogroup>`);
|
|
194
|
+
|
|
195
|
+
const radio1 = el.querySelectorAll("sgds-radio")[0];
|
|
196
|
+
const radio2 = el.querySelectorAll("sgds-radio")[1];
|
|
197
|
+
const radio3 = el.querySelectorAll("sgds-radio")[2];
|
|
198
|
+
|
|
199
|
+
radio1.click();
|
|
200
|
+
await el.updateComplete;
|
|
201
|
+
|
|
202
|
+
expect(radio1).to.have.attribute("tabindex", "0");
|
|
203
|
+
expect(radio2).to.have.attribute("tabindex", "-1");
|
|
204
|
+
expect(radio3).to.have.attribute("tabindex", "-1");
|
|
205
|
+
|
|
206
|
+
radio2.click();
|
|
207
|
+
await el.updateComplete;
|
|
208
|
+
|
|
209
|
+
expect(radio1).to.have.attribute("tabindex", "-1");
|
|
210
|
+
expect(radio2).to.have.attribute("tabindex", "0");
|
|
211
|
+
expect(radio3).to.have.attribute("tabindex", "-1");
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("clicking label should focus on first radio when radios unchecked", async () => {
|
|
215
|
+
const el = await fixture<SgdsRadioGroup>(html`<sgds-radiogroup
|
|
216
|
+
label="Hello world"
|
|
217
|
+
>
|
|
218
|
+
<sgds-radio value="1">one</sgds-radio>
|
|
219
|
+
<sgds-radio value="2">two</sgds-radio>
|
|
220
|
+
<sgds-radio value="3">three</sgds-radio>
|
|
221
|
+
</sgds-radiogroup>`);
|
|
222
|
+
|
|
223
|
+
const radio1 = el.querySelectorAll("sgds-radio")[0];
|
|
224
|
+
|
|
225
|
+
const label = <HTMLLabelElement>(
|
|
226
|
+
el.shadowRoot?.querySelector("label.form-label")
|
|
227
|
+
);
|
|
228
|
+
label.click();
|
|
229
|
+
|
|
230
|
+
await triggerFocusFor(radio1);
|
|
231
|
+
expect(document.activeElement === radio1).to.be.true;
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it("when a radio is checked, clicking label should focus on the checked radio", async () => {
|
|
235
|
+
const el = await fixture<SgdsRadioGroup>(html`<sgds-radiogroup
|
|
236
|
+
label="Hello world"
|
|
237
|
+
>
|
|
238
|
+
<sgds-radio value="1">one</sgds-radio>
|
|
239
|
+
<sgds-radio value="2">two</sgds-radio>
|
|
240
|
+
<sgds-radio value="3">three</sgds-radio>
|
|
241
|
+
</sgds-radiogroup>`);
|
|
242
|
+
|
|
243
|
+
const radio2 = el.querySelectorAll("sgds-radio")[1];
|
|
244
|
+
|
|
245
|
+
radio2.click();
|
|
246
|
+
await el.updateComplete;
|
|
247
|
+
|
|
248
|
+
const label = <HTMLLabelElement>(
|
|
249
|
+
el.shadowRoot?.querySelector("label.form-label")
|
|
250
|
+
);
|
|
251
|
+
label.click();
|
|
252
|
+
|
|
253
|
+
await triggerFocusFor(radio2);
|
|
254
|
+
expect(document.activeElement === radio2).to.be.true;
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("should allow for the following keyboard interactions upon keydown", async () => {
|
|
258
|
+
const el = await fixture<SgdsRadioGroup>(html`<sgds-radiogroup
|
|
259
|
+
label="Hello world"
|
|
260
|
+
>
|
|
261
|
+
<sgds-radio value="1">one</sgds-radio>
|
|
262
|
+
<sgds-radio value="2">two</sgds-radio>
|
|
263
|
+
<sgds-radio value="3">three</sgds-radio>
|
|
264
|
+
</sgds-radiogroup>`);
|
|
265
|
+
|
|
266
|
+
const radio1 = el.querySelectorAll("sgds-radio")[0];
|
|
267
|
+
const radio2 = el.querySelectorAll("sgds-radio")[1];
|
|
268
|
+
const radio3 = el.querySelectorAll("sgds-radio")[2];
|
|
269
|
+
|
|
270
|
+
const label = <HTMLLabelElement>(
|
|
271
|
+
el.shadowRoot?.querySelector("label.form-label")
|
|
272
|
+
);
|
|
273
|
+
label.click();
|
|
274
|
+
|
|
275
|
+
await triggerFocusFor(radio1);
|
|
276
|
+
expect(document.activeElement === radio1).to.be.true;
|
|
277
|
+
|
|
278
|
+
// spacebar key
|
|
279
|
+
await sendKeys({ press: " " });
|
|
280
|
+
expect(radio1).to.have.attribute("tabindex", "0");
|
|
281
|
+
expect(radio1).to.have.attribute("aria-checked", "true");
|
|
282
|
+
expect(el).to.have.attribute("value", "1");
|
|
283
|
+
|
|
284
|
+
// arrowright incr index
|
|
285
|
+
await sendKeys({ press: "ArrowRight" });
|
|
286
|
+
expect(radio2).to.have.attribute("tabindex", "0");
|
|
287
|
+
expect(radio2).to.have.attribute("aria-checked", "true");
|
|
288
|
+
expect(el).to.have.attribute("value", "2");
|
|
289
|
+
|
|
290
|
+
// arrowdown incr index
|
|
291
|
+
await sendKeys({ press: "ArrowDown" });
|
|
292
|
+
expect(radio3).to.have.attribute("tabindex", "0");
|
|
293
|
+
expect(radio3).to.have.attribute("aria-checked", "true");
|
|
294
|
+
expect(el).to.have.attribute("value", "3");
|
|
295
|
+
|
|
296
|
+
// arrowleft decr index
|
|
297
|
+
await sendKeys({ press: "ArrowLeft" });
|
|
298
|
+
expect(radio2).to.have.attribute("tabindex", "0");
|
|
299
|
+
expect(radio2).to.have.attribute("aria-checked", "true");
|
|
300
|
+
expect(el).to.have.attribute("value", "2");
|
|
301
|
+
|
|
302
|
+
// arrowup decr index
|
|
303
|
+
await sendKeys({ press: "ArrowLeft" });
|
|
304
|
+
expect(radio1).to.have.attribute("tabindex", "0");
|
|
305
|
+
expect(radio1).to.have.attribute("aria-checked", "true");
|
|
306
|
+
expect(el).to.have.attribute("value", "1");
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Keyboard interactions (arrowdown, arrowup) --> to keep check on the handleKeyDown() you wrote --> and that it updates the sgds-radio-group
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aTimeout,
|
|
3
|
+
expect,
|
|
4
|
+
fixture,
|
|
5
|
+
html,
|
|
6
|
+
oneEvent,
|
|
7
|
+
assert,
|
|
8
|
+
waitUntil,
|
|
9
|
+
elementUpdated,
|
|
10
|
+
} from "@open-wc/testing";
|
|
11
|
+
import sinon from "sinon";
|
|
12
|
+
import "../src/Card";
|
|
13
|
+
import { SgdsActionCard } from "../src/Card";
|
|
14
|
+
import "../src/Checkbox";
|
|
15
|
+
import "../src/Radio";
|
|
16
|
+
import { SgdsCheckbox } from "../src/Checkbox";
|
|
17
|
+
import { SgdsButton } from "../src/Button";
|
|
18
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
19
|
+
import { CardElement } from "../src/utils/card-element";
|
|
20
|
+
import { Button } from "bootstrap";
|
|
21
|
+
|
|
22
|
+
describe("<sgds-action-card>", () => {
|
|
23
|
+
// Card test cases
|
|
24
|
+
it("is defined", () => {
|
|
25
|
+
const el = document.createElement("sgds-action-card");
|
|
26
|
+
assert.instanceOf(el, SgdsActionCard);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should have sgds prefix on wrapper", async () => {
|
|
30
|
+
const el = await fixture(html`<sgds-action-card></sgds-action-card>`);
|
|
31
|
+
const slCard = el.shadowRoot?.querySelector("div");
|
|
32
|
+
expect(slCard?.classList.value).to.contain("sgds");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("accepts a bg prop", async () => {
|
|
36
|
+
const el = await fixture(html`<sgds-action-card></sgds-action-card>`);
|
|
37
|
+
el?.setAttribute("bgColor", "primary");
|
|
38
|
+
await elementUpdated(el);
|
|
39
|
+
const bgColor = el.shadowRoot?.querySelector("div");
|
|
40
|
+
expect(bgColor?.classList.value).to.contain("bg-primary");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("accepts a text prop", async () => {
|
|
44
|
+
const el = await fixture(html`<sgds-action-card></sgds-action-card>`);
|
|
45
|
+
el?.setAttribute("borderColor", "primary");
|
|
46
|
+
await elementUpdated(el);
|
|
47
|
+
const borderColor = el.shadowRoot?.querySelector("div");
|
|
48
|
+
expect(borderColor?.classList.value).to.contain("border-primary");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("accepts a border prop", async () => {
|
|
52
|
+
const el = await fixture(html`<sgds-action-card></sgds-action-card>`);
|
|
53
|
+
el?.setAttribute("textColor", "primary");
|
|
54
|
+
await elementUpdated(el);
|
|
55
|
+
const bgColor = el.shadowRoot?.querySelector("div");
|
|
56
|
+
expect(bgColor?.classList.value).to.contain("text-primary");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("can be semantically compare with shadowDom trees", async () => {
|
|
60
|
+
const el = await fixture(
|
|
61
|
+
html`<sgds-action-card inputId="checkbox"></sgds-action-card>`
|
|
62
|
+
);
|
|
63
|
+
assert.shadowDom.equal(
|
|
64
|
+
el,
|
|
65
|
+
`
|
|
66
|
+
<div tabindex="0" variant="card-action" class="sgds card
|
|
67
|
+
|
|
68
|
+
">
|
|
69
|
+
<div class="card-body">
|
|
70
|
+
<h6 class="text-muted card-subtitle">
|
|
71
|
+
<div>
|
|
72
|
+
|
|
73
|
+
<slot name="card-subtitle"></slot>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="card-input">
|
|
76
|
+
<sgds-checkbox checkboxid="checkbox" arialabel="checkbox"></sgds-checkbox>
|
|
77
|
+
</div>
|
|
78
|
+
</h6>
|
|
79
|
+
<h5 class="card-title"><slot name="card-title"></slot></h5>
|
|
80
|
+
<p class="card-text"><slot name="card-text"></slot></p>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
`
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("it should have type checkbox and variant card-action by default", async () => {
|
|
88
|
+
const el = await fixture(html`<sgds-action-card></sgds-action-card>`);
|
|
89
|
+
expect(el?.getAttribute("type")).to.equal("checkbox");
|
|
90
|
+
expect(el?.getAttribute("variant")).to.equal("card-action");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("it should have type radio when specified", async () => {
|
|
94
|
+
const el = await fixture(
|
|
95
|
+
html`<sgds-action-card type="radio"></sgds-action-card>`
|
|
96
|
+
);
|
|
97
|
+
expect(el?.getAttribute("type")).to.equal("radio");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("when card is clicked, card should contain class is-active", async () => {
|
|
101
|
+
const el = await fixture<SgdsActionCard>(
|
|
102
|
+
html`<sgds-action-card></sgds-action-card>`
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.not.have.class(
|
|
106
|
+
"is-active"
|
|
107
|
+
);
|
|
108
|
+
const cardBody = el.shadowRoot?.querySelector(
|
|
109
|
+
"div.card-body"
|
|
110
|
+
) as HTMLInputElement;
|
|
111
|
+
cardBody.click();
|
|
112
|
+
await el.updateComplete;
|
|
113
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.have.class(
|
|
114
|
+
"is-active"
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("when card is disabled, card should be clickable and does not contain class is-active", async () => {
|
|
119
|
+
const el = await fixture<SgdsActionCard>(
|
|
120
|
+
html`<sgds-action-card disabled></sgds-action-card>`
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.not.have.class(
|
|
124
|
+
"is-active"
|
|
125
|
+
);
|
|
126
|
+
const cardBody = el.shadowRoot?.querySelector(
|
|
127
|
+
"div.card-body"
|
|
128
|
+
) as HTMLInputElement;
|
|
129
|
+
cardBody.click();
|
|
130
|
+
await el.updateComplete;
|
|
131
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.not.have.class(
|
|
132
|
+
"is-active"
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("when card is focus, card should be able to be checked with key Enter and contains class is-active", async () => {
|
|
137
|
+
const el = await fixture<SgdsActionCard>(
|
|
138
|
+
html`<sgds-action-card></sgds-action-card>`
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.not.have.class(
|
|
142
|
+
"is-active"
|
|
143
|
+
);
|
|
144
|
+
// const cardBody = el.shadowRoot?.querySelector(
|
|
145
|
+
// "div.card-body"
|
|
146
|
+
// ) as HTMLInputElement;
|
|
147
|
+
const card = el.shadowRoot?.querySelector(
|
|
148
|
+
"div.sgds.card"
|
|
149
|
+
) as HTMLInputElement;
|
|
150
|
+
card.focus();
|
|
151
|
+
await sendKeys({ press: "Enter" });
|
|
152
|
+
await el.updateComplete;
|
|
153
|
+
expect(el.shadowRoot?.querySelector("div.sgds.card")).to.have.class(
|
|
154
|
+
"is-active"
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
|