@govtechsg/sgds-web-component 0.0.8 → 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 +2785 -9262
- 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} +3870 -23414
- 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 +2 -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 -52097
- package/umd/index.js.map +0 -1
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import { SgdsDropdown, SgdsDropdownItem } from "../src/Dropdown";
|
|
2
|
+
import { SgdsButton } from "../src/Button";
|
|
3
|
+
import "../src/Dropdown";
|
|
4
|
+
import {
|
|
5
|
+
fixture,
|
|
6
|
+
assert,
|
|
7
|
+
expect,
|
|
8
|
+
waitUntil,
|
|
9
|
+
} from "@open-wc/testing";
|
|
10
|
+
import sinon from "sinon";
|
|
11
|
+
import { html } from "lit";
|
|
12
|
+
import { sendKeys, sendMouse } from "@web/test-runner-commands";
|
|
13
|
+
import { MockDropdown } from "../mocks/dropdown";
|
|
14
|
+
import "../mocks/dropdown";
|
|
15
|
+
|
|
16
|
+
describe('dropdown-element generic keyboard interactions', () => {
|
|
17
|
+
// //keyboard navigation
|
|
18
|
+
const closeKeys = ["Enter", "Escape"];
|
|
19
|
+
closeKeys.forEach((key) => {
|
|
20
|
+
it(`should close an opened menu on ${key} press`, async () => {
|
|
21
|
+
const el = await fixture<MockDropdown>(
|
|
22
|
+
html`<mock-dropdown menuIsOpen>
|
|
23
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
24
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
25
|
+
</mock-dropdown> `
|
|
26
|
+
);
|
|
27
|
+
expect(el.menuIsOpen).to.be.true;
|
|
28
|
+
el.shadowRoot?.querySelector("button")?.focus();
|
|
29
|
+
await waitUntil(() => el.shadowRoot?.querySelector("button:focus"));
|
|
30
|
+
await sendKeys({ press: key });
|
|
31
|
+
await el.updateComplete;
|
|
32
|
+
await waitUntil(
|
|
33
|
+
() => !el.shadowRoot?.querySelector("ul.dropdown-menu.show"),
|
|
34
|
+
"element should disappear",
|
|
35
|
+
{ timeout: 3000 }
|
|
36
|
+
);
|
|
37
|
+
expect(el.menuIsOpen).to.be.false;
|
|
38
|
+
}).retries(1);
|
|
39
|
+
});
|
|
40
|
+
const openKeys = ["ArrowDown", "ArrowUp", "Enter"];
|
|
41
|
+
openKeys.forEach((key) => {
|
|
42
|
+
it(`should open menu on ${key} key`, async () => {
|
|
43
|
+
const el = await fixture<MockDropdown>(
|
|
44
|
+
html`<mock-dropdown>
|
|
45
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
46
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
47
|
+
</mock-dropdown> `
|
|
48
|
+
);
|
|
49
|
+
expect(el.menuIsOpen).to.be.false;
|
|
50
|
+
el.shadowRoot?.querySelector("button")?.focus();
|
|
51
|
+
await sendKeys({ press: key });
|
|
52
|
+
await waitUntil(() =>
|
|
53
|
+
el.shadowRoot?.querySelector("ul.dropdown-menu.show")
|
|
54
|
+
);
|
|
55
|
+
expect(el.menuIsOpen).to.be.true;
|
|
56
|
+
}).retries(1); // allowing retries as these tests tends to be flaky on firefox
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("for a newly opened menu with no focus on any items, ArrowDown key will navigate to the first dropdown-item on the menu and continue looping once it reaches the last menu item", async () => {
|
|
60
|
+
const el = await fixture<MockDropdown>(
|
|
61
|
+
html`<mock-dropdown menuIsOpen>
|
|
62
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
63
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
64
|
+
</mock-dropdown> `
|
|
65
|
+
);
|
|
66
|
+
expect(el.nextDropdownItemNo).to.equal(0);
|
|
67
|
+
expect(el.prevDropdownItemNo).to.equal(-1);
|
|
68
|
+
el.shadowRoot?.querySelector("button")?.focus();
|
|
69
|
+
|
|
70
|
+
await sendKeys({ press: "ArrowDown" });
|
|
71
|
+
// currentItem = 0
|
|
72
|
+
await el.updateComplete;
|
|
73
|
+
expect(el.nextDropdownItemNo).to.equal(1);
|
|
74
|
+
expect(el.prevDropdownItemNo).to.equal(1);
|
|
75
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
76
|
+
"tabindex",
|
|
77
|
+
"0"
|
|
78
|
+
);
|
|
79
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
80
|
+
"tabindex",
|
|
81
|
+
"-1"
|
|
82
|
+
);
|
|
83
|
+
await sendKeys({ press: "ArrowDown" });
|
|
84
|
+
//currentItem = 1
|
|
85
|
+
await el.updateComplete;
|
|
86
|
+
expect(el.nextDropdownItemNo).to.equal(2);
|
|
87
|
+
expect(el.prevDropdownItemNo).to.equal(0);
|
|
88
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
89
|
+
"tabindex",
|
|
90
|
+
"-1"
|
|
91
|
+
);
|
|
92
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
93
|
+
"tabindex",
|
|
94
|
+
"0"
|
|
95
|
+
);
|
|
96
|
+
await sendKeys({ press: "ArrowDown" });
|
|
97
|
+
//currentItem = 0
|
|
98
|
+
await el.updateComplete;
|
|
99
|
+
expect(el.nextDropdownItemNo).to.equal(1);
|
|
100
|
+
expect(el.prevDropdownItemNo).to.equal(1);
|
|
101
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
102
|
+
"tabindex",
|
|
103
|
+
"0"
|
|
104
|
+
);
|
|
105
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
106
|
+
"tabindex",
|
|
107
|
+
"-1"
|
|
108
|
+
);
|
|
109
|
+
}).retries(1);
|
|
110
|
+
it("for a newly opened menu with no focus on any items, ArrowUp key will navigate to the last dropdown-item on the menu and continue looping once it reaches the last menu item", async () => {
|
|
111
|
+
const el = await fixture<MockDropdown>(
|
|
112
|
+
html`<mock-dropdown menuIsOpen>
|
|
113
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
114
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
115
|
+
</mock-dropdown> `
|
|
116
|
+
);
|
|
117
|
+
expect(el.nextDropdownItemNo).to.equal(0);
|
|
118
|
+
expect(el.prevDropdownItemNo).to.equal(-1);
|
|
119
|
+
el.shadowRoot?.querySelector("button")?.focus();
|
|
120
|
+
await sendKeys({ press: "ArrowUp" });
|
|
121
|
+
// currentItem = 1
|
|
122
|
+
await el.updateComplete;
|
|
123
|
+
expect(el.nextDropdownItemNo).to.equal(2);
|
|
124
|
+
expect(el.prevDropdownItemNo).to.equal(0);
|
|
125
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
126
|
+
"tabindex",
|
|
127
|
+
"-1"
|
|
128
|
+
);
|
|
129
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
130
|
+
"tabindex",
|
|
131
|
+
"0"
|
|
132
|
+
);
|
|
133
|
+
await sendKeys({ press: "ArrowUp" });
|
|
134
|
+
//currentItem = 0
|
|
135
|
+
await el.updateComplete;
|
|
136
|
+
expect(el.nextDropdownItemNo).to.equal(1);
|
|
137
|
+
expect(el.prevDropdownItemNo).to.equal(1);
|
|
138
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
139
|
+
"tabindex",
|
|
140
|
+
"0"
|
|
141
|
+
);
|
|
142
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
143
|
+
"tabindex",
|
|
144
|
+
"-1"
|
|
145
|
+
);
|
|
146
|
+
await sendKeys({ press: "ArrowUp" });
|
|
147
|
+
//currentItem = 1
|
|
148
|
+
await el.updateComplete;
|
|
149
|
+
expect(el.nextDropdownItemNo).to.equal(2);
|
|
150
|
+
expect(el.prevDropdownItemNo).to.equal(0);
|
|
151
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).to.have.attribute(
|
|
152
|
+
"tabindex",
|
|
153
|
+
"-1"
|
|
154
|
+
);
|
|
155
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).to.have.attribute(
|
|
156
|
+
"tabindex",
|
|
157
|
+
"0"
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
//closing the menu resets the states nextDropdownItemNo and prevDropdownItemNo
|
|
161
|
+
await sendKeys({ press: "Escape" });
|
|
162
|
+
await el.updateComplete;
|
|
163
|
+
expect(el.menuIsOpen).to.be.false;
|
|
164
|
+
expect(el.nextDropdownItemNo).to.equal(0);
|
|
165
|
+
expect(el.prevDropdownItemNo).to.equal(-1);
|
|
166
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[0]).not.to.have.attribute(
|
|
167
|
+
"tabindex" );
|
|
168
|
+
expect(el.querySelectorAll("sgds-dropdown-item")[1]).not.to.have.attribute(
|
|
169
|
+
"tabindex",
|
|
170
|
+
);
|
|
171
|
+
}).retries(1);
|
|
172
|
+
it("keyboard navigation skips disabled items", async () => {
|
|
173
|
+
const el = await fixture<MockDropdown>(
|
|
174
|
+
html`<mock-dropdown menuIsOpen>
|
|
175
|
+
<sgds-dropdown-item disabled>slot 1</sgds-dropdown-item>
|
|
176
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
177
|
+
<sgds-dropdown-item>slot 3</sgds-dropdown-item>
|
|
178
|
+
<sgds-dropdown-item disabled>slot 4</sgds-dropdown-item>
|
|
179
|
+
</mock-dropdown> `
|
|
180
|
+
);
|
|
181
|
+
el.shadowRoot?.querySelector("button")?.focus();
|
|
182
|
+
await sendKeys({ press: "ArrowDown" });
|
|
183
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
184
|
+
el.querySelectorAll("sgds-dropdown-item")[1]
|
|
185
|
+
);
|
|
186
|
+
await sendKeys({ press: "ArrowDown" });
|
|
187
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
188
|
+
el.querySelectorAll("sgds-dropdown-item")[2]
|
|
189
|
+
);
|
|
190
|
+
await sendKeys({ press: "ArrowDown" });
|
|
191
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
192
|
+
el.querySelectorAll("sgds-dropdown-item")[1]
|
|
193
|
+
);
|
|
194
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).not.to.equal(
|
|
195
|
+
el.querySelectorAll("sgds-dropdown-item")[3]
|
|
196
|
+
);
|
|
197
|
+
}).retries(1);
|
|
198
|
+
// test case: when close="outside" and user mouse clicks on menu and then change to keyboard navigation
|
|
199
|
+
it("transition from mouse click to keyboard navigation should be seamless", async () => {
|
|
200
|
+
const el = await fixture<MockDropdown>(
|
|
201
|
+
html`<mock-dropdown menuIsOpen close="outside">
|
|
202
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
203
|
+
<sgds-dropdown-item disabled>slot 2</sgds-dropdown-item>
|
|
204
|
+
<sgds-dropdown-item>slot 3</sgds-dropdown-item>
|
|
205
|
+
<sgds-dropdown-item>slot 4</sgds-dropdown-item>
|
|
206
|
+
</mock-dropdown> `
|
|
207
|
+
);
|
|
208
|
+
const itemOne = el.querySelectorAll(
|
|
209
|
+
"sgds-dropdown-item"
|
|
210
|
+
)[0] as SgdsDropdownItem;
|
|
211
|
+
itemOne.click();
|
|
212
|
+
await sendKeys({ press: "ArrowDown" });
|
|
213
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
214
|
+
el.querySelectorAll("sgds-dropdown-item")[2]
|
|
215
|
+
);
|
|
216
|
+
await sendKeys({ press: "ArrowDown" });
|
|
217
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).not.to.equal(
|
|
218
|
+
el.querySelectorAll("sgds-dropdown-item")[2]
|
|
219
|
+
);
|
|
220
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
221
|
+
el.querySelectorAll("sgds-dropdown-item")[3]
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
itemOne.click();
|
|
225
|
+
await sendKeys({ press: "ArrowUp" });
|
|
226
|
+
expect(el.querySelector("sgds-dropdown-item:focus")).to.equal(
|
|
227
|
+
el.querySelectorAll("sgds-dropdown-item")[3]
|
|
228
|
+
);
|
|
229
|
+
}).retries(1);
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe("sgds-dropdown", () => {
|
|
233
|
+
it("is defined", () => {
|
|
234
|
+
const el = document.createElement("sgds-dropdown");
|
|
235
|
+
assert.instanceOf(el, SgdsDropdown);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("can be semantically compare with shadowDom trees", async () => {
|
|
239
|
+
const el = await fixture(
|
|
240
|
+
html`<sgds-dropdown togglerId="dropdown-test-id"></sgds-dropdown>`
|
|
241
|
+
);
|
|
242
|
+
assert.shadowDom.equal(
|
|
243
|
+
el,
|
|
244
|
+
` <div>
|
|
245
|
+
<sgds-button
|
|
246
|
+
aria-expanded="false"
|
|
247
|
+
id="dropdown-test-id"
|
|
248
|
+
variant="outline-secondary"
|
|
249
|
+
>
|
|
250
|
+
<svg
|
|
251
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
252
|
+
width="16"
|
|
253
|
+
height="16"
|
|
254
|
+
fill="currentColor"
|
|
255
|
+
class="bi bi-chevron-down"
|
|
256
|
+
viewBox="0 0 16 16"
|
|
257
|
+
>
|
|
258
|
+
<path
|
|
259
|
+
fill-rule="evenodd"
|
|
260
|
+
d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"
|
|
261
|
+
/>
|
|
262
|
+
</svg>
|
|
263
|
+
</sgds-button>
|
|
264
|
+
<ul
|
|
265
|
+
class="dropdown-menu"
|
|
266
|
+
part="menu"
|
|
267
|
+
role="menu"
|
|
268
|
+
>
|
|
269
|
+
<slot>
|
|
270
|
+
</slot>
|
|
271
|
+
</ul>
|
|
272
|
+
</div>
|
|
273
|
+
`
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
it("when disabled is true, toggle is disabled ", async () => {
|
|
277
|
+
const el = await fixture<SgdsDropdown>(
|
|
278
|
+
html`<sgds-dropdown disabled></sgds-dropdown>`
|
|
279
|
+
);
|
|
280
|
+
expect(el.shadowRoot?.querySelector("sgds-button")).to.have.attribute(
|
|
281
|
+
"disabled"
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
it("when menuAlignRight is false (default) on default dropdown, data-popper-placement on ul.dropdown-menu is bottom-start ", async () => {
|
|
285
|
+
const el = await fixture<SgdsDropdown>(
|
|
286
|
+
html`<sgds-dropdown></sgds-dropdown>`
|
|
287
|
+
);
|
|
288
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
289
|
+
await waitUntil(() =>
|
|
290
|
+
el.shadowRoot?.querySelector("ul.dropdown-menu.show")
|
|
291
|
+
);
|
|
292
|
+
expect(
|
|
293
|
+
el.shadowRoot
|
|
294
|
+
?.querySelector("ul.dropdown-menu")
|
|
295
|
+
?.getAttribute("data-popper-placement")
|
|
296
|
+
).to.equal("bottom-start");
|
|
297
|
+
});
|
|
298
|
+
// //Popper attri data-popper-placemetn not responding to test changes in open-wc
|
|
299
|
+
// //unsure why not working when console logging values are bottom-end
|
|
300
|
+
it("when menuAlignRight is true on default dropdown, dropdownConfig placement is bottom-end ", async () => {
|
|
301
|
+
const el = await fixture<SgdsDropdown>(
|
|
302
|
+
html`<sgds-dropdown menuAlignRight></sgds-dropdown>`
|
|
303
|
+
);
|
|
304
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
305
|
+
|
|
306
|
+
expect(el.dropdownConfig.placement).to.equal("bottom-end");
|
|
307
|
+
});
|
|
308
|
+
it("when menuAlignRight is true on dropup, dropdownConfig placement is top-end ", async () => {
|
|
309
|
+
const el = await fixture<SgdsDropdown>(
|
|
310
|
+
html`<sgds-dropdown menuAlignRight drop="up"></sgds-dropdown>`
|
|
311
|
+
);
|
|
312
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
313
|
+
|
|
314
|
+
expect(el.dropdownConfig.placement).to.equal("top-end");
|
|
315
|
+
});
|
|
316
|
+
it("when menuAlignRight is false on dropup, dropdownConfig placement is top-start", async () => {
|
|
317
|
+
const el = await fixture<SgdsDropdown>(
|
|
318
|
+
html`<sgds-dropdown drop="up"></sgds-dropdown>`
|
|
319
|
+
);
|
|
320
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
321
|
+
|
|
322
|
+
expect(el.dropdownConfig.placement).to.equal("top-start");
|
|
323
|
+
});
|
|
324
|
+
it("when dropright, dropdownConfig placement is right-start ", async () => {
|
|
325
|
+
const el = await fixture<SgdsDropdown>(
|
|
326
|
+
html`<sgds-dropdown drop="right"></sgds-dropdown>`
|
|
327
|
+
);
|
|
328
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
329
|
+
|
|
330
|
+
expect(el.dropdownConfig.placement).to.equal("right-start");
|
|
331
|
+
});
|
|
332
|
+
it("when dropleft, dropdownConfig placement is left-start ", async () => {
|
|
333
|
+
const el = await fixture<SgdsDropdown>(
|
|
334
|
+
html`<sgds-dropdown drop="left"></sgds-dropdown>`
|
|
335
|
+
);
|
|
336
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
337
|
+
|
|
338
|
+
expect(el.dropdownConfig.placement).to.equal("left-start");
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("when noFlip is false, dropdownConfig.modifiers array has only offset obj", async () => {
|
|
342
|
+
const el = await fixture<SgdsDropdown>(
|
|
343
|
+
html`<sgds-dropdown></sgds-dropdown>`
|
|
344
|
+
);
|
|
345
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
346
|
+
expect(el.dropdownConfig.modifiers?.length).to.equal(1);
|
|
347
|
+
expect(el.dropdownConfig.modifiers?.[0].name).to.equal("offset");
|
|
348
|
+
expect(el.dropdownConfig.modifiers?.[0].options?.offset[0]).to.equal(0);
|
|
349
|
+
expect(el.dropdownConfig.modifiers?.[0].options?.offset[1]).to.equal(10);
|
|
350
|
+
});
|
|
351
|
+
it("when noFlip is true, dropdownConfig.modifiers array has flip obj", async () => {
|
|
352
|
+
const el = await fixture<SgdsDropdown>(
|
|
353
|
+
html`<sgds-dropdown noFlip></sgds-dropdown>`
|
|
354
|
+
);
|
|
355
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
356
|
+
expect(el.dropdownConfig.modifiers?.length).to.equal(2);
|
|
357
|
+
expect(el.dropdownConfig.modifiers?.[1].name).to.equal("flip");
|
|
358
|
+
});
|
|
359
|
+
it("togglerText prop is forwarded to text content of button element", async () => {
|
|
360
|
+
const el = await fixture<SgdsDropdown>(
|
|
361
|
+
html`<sgds-dropdown togglerText="Hello World"></sgds-dropdown>`
|
|
362
|
+
);
|
|
363
|
+
expect(el.shadowRoot?.querySelector("sgds-button")?.textContent).to.contain(
|
|
364
|
+
"Hello World"
|
|
365
|
+
);
|
|
366
|
+
});
|
|
367
|
+
it("variant prop is forwarded to text content of sgds-button element", async () => {
|
|
368
|
+
const el = await fixture<SgdsDropdown>(
|
|
369
|
+
html`<sgds-dropdown variant="primary"></sgds-dropdown>`
|
|
370
|
+
);
|
|
371
|
+
expect(el.shadowRoot?.querySelector("sgds-button")).to.have.attribute(
|
|
372
|
+
"variant",
|
|
373
|
+
"outline-primary"
|
|
374
|
+
);
|
|
375
|
+
});
|
|
376
|
+
it("menuIsOpen prop opens menu on first load", async () => {
|
|
377
|
+
const el = await fixture<SgdsDropdown>(
|
|
378
|
+
html`<sgds-dropdown menuIsOpen></sgds-dropdown>`
|
|
379
|
+
);
|
|
380
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
381
|
+
"show"
|
|
382
|
+
);
|
|
383
|
+
});
|
|
384
|
+
// //emits events when dropdown is toggle open/close
|
|
385
|
+
it("emits sgds-show/shown/hide/hidden events when dropdown toggles", async () => {
|
|
386
|
+
const el = await fixture<SgdsDropdown>(
|
|
387
|
+
html`<sgds-dropdown></sgds-dropdown>`
|
|
388
|
+
);
|
|
389
|
+
const showHandler = sinon.spy();
|
|
390
|
+
const shownHandler = sinon.spy();
|
|
391
|
+
const hideHandler = sinon.spy();
|
|
392
|
+
const hiddenHandler = sinon.spy();
|
|
393
|
+
el.addEventListener("sgds-show", showHandler);
|
|
394
|
+
el.addEventListener("sgds-shown", shownHandler);
|
|
395
|
+
el.addEventListener("sgds-hide", hideHandler);
|
|
396
|
+
el.addEventListener("sgds-hidden", hiddenHandler);
|
|
397
|
+
|
|
398
|
+
const button = el.shadowRoot?.querySelector("sgds-button") as SgdsButton;
|
|
399
|
+
button?.click();
|
|
400
|
+
await el.updateComplete;
|
|
401
|
+
expect(showHandler).to.be.calledOnce;
|
|
402
|
+
expect(shownHandler).to.be.calledAfter(showHandler);
|
|
403
|
+
expect(shownHandler).to.be.calledOnce;
|
|
404
|
+
expect(hideHandler).not.to.be.called;
|
|
405
|
+
expect(hiddenHandler).not.to.be.called;
|
|
406
|
+
|
|
407
|
+
button?.click();
|
|
408
|
+
expect(hideHandler).to.be.calledOnce;
|
|
409
|
+
expect(hiddenHandler).to.be.calledAfter(hideHandler);
|
|
410
|
+
expect(hiddenHandler).to.be.calledOnce;
|
|
411
|
+
});
|
|
412
|
+
it("showMenu/hideMenu method opens/closes menu", async () => {
|
|
413
|
+
const el = await fixture<SgdsDropdown>(
|
|
414
|
+
html`<sgds-dropdown></sgds-dropdown>`
|
|
415
|
+
);
|
|
416
|
+
expect(el.menuIsOpen).to.be.false;
|
|
417
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
418
|
+
"show"
|
|
419
|
+
);
|
|
420
|
+
el.showMenu();
|
|
421
|
+
await el.updateComplete;
|
|
422
|
+
expect(el.menuIsOpen).to.be.true;
|
|
423
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
424
|
+
"show"
|
|
425
|
+
);
|
|
426
|
+
el.hideMenu();
|
|
427
|
+
await el.updateComplete;
|
|
428
|
+
expect(el.menuIsOpen).to.be.false;
|
|
429
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
430
|
+
"show"
|
|
431
|
+
);
|
|
432
|
+
});
|
|
433
|
+
// // testing _handleSelectSlot functionality
|
|
434
|
+
it("emits sgds-select event when its slots are clicked on", async () => {
|
|
435
|
+
const el = await fixture<SgdsDropdown>(
|
|
436
|
+
html`<sgds-dropdown>
|
|
437
|
+
<div>slot 1</div>
|
|
438
|
+
<div>slot 2</div>
|
|
439
|
+
</sgds-dropdown>`
|
|
440
|
+
);
|
|
441
|
+
const selectHandler = sinon.spy();
|
|
442
|
+
el.addEventListener("sgds-select", selectHandler);
|
|
443
|
+
|
|
444
|
+
const slots = el.shadowRoot
|
|
445
|
+
?.querySelector("slot")
|
|
446
|
+
?.assignedElements({ flatten: true }) as HTMLElement[];
|
|
447
|
+
expect(slots?.length).to.equal(2);
|
|
448
|
+
expect(slots?.[0].tagName).to.equal("DIV");
|
|
449
|
+
slots?.[0].click();
|
|
450
|
+
slots?.[1].click();
|
|
451
|
+
expect(selectHandler).to.be.calledTwice;
|
|
452
|
+
});
|
|
453
|
+
it("does not emit sgds-select event when its disabled slots are clicked on", async () => {
|
|
454
|
+
const el = await fixture<SgdsDropdown>(
|
|
455
|
+
html`<sgds-dropdown>
|
|
456
|
+
<sgds-dropdown-item disabled>slot 1</sgds-dropdown-item>
|
|
457
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
458
|
+
</sgds-dropdown>`
|
|
459
|
+
);
|
|
460
|
+
const selectHandler = sinon.spy();
|
|
461
|
+
el.addEventListener("sgds-select", selectHandler);
|
|
462
|
+
|
|
463
|
+
const slots = el.shadowRoot
|
|
464
|
+
?.querySelector("slot")
|
|
465
|
+
?.assignedElements({ flatten: true }) as SgdsDropdownItem[];
|
|
466
|
+
slots?.[0].click();
|
|
467
|
+
expect(selectHandler).not.to.be.called;
|
|
468
|
+
});
|
|
469
|
+
// // testing _handleSelectSlot functionality
|
|
470
|
+
it("when clicked on slot, menu closes", async () => {
|
|
471
|
+
const el = await fixture<SgdsDropdown>(
|
|
472
|
+
html`<sgds-dropdown menuIsOpen>
|
|
473
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
474
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
475
|
+
</sgds-dropdown>`
|
|
476
|
+
);
|
|
477
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
478
|
+
"show"
|
|
479
|
+
);
|
|
480
|
+
const slots = el.shadowRoot
|
|
481
|
+
?.querySelector("slot")
|
|
482
|
+
?.assignedElements({ flatten: true }) as HTMLElement[];
|
|
483
|
+
|
|
484
|
+
slots?.[0].click();
|
|
485
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
486
|
+
"show"
|
|
487
|
+
);
|
|
488
|
+
});
|
|
489
|
+
// // tests _handleClickOutOfElement & blur event listener
|
|
490
|
+
it("click outside of component, closes the dropdown by default", async () => {
|
|
491
|
+
const el = await fixture<SgdsDropdown>(
|
|
492
|
+
html`<sgds-dropdown menuIsOpen>
|
|
493
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
494
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
495
|
+
</sgds-dropdown> `
|
|
496
|
+
);
|
|
497
|
+
expect(el.menuIsOpen).to.be.true;
|
|
498
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
499
|
+
"show"
|
|
500
|
+
);
|
|
501
|
+
await sendMouse({ type: "click", position: [0, 0] });
|
|
502
|
+
await el.updateComplete;
|
|
503
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
504
|
+
"show"
|
|
505
|
+
);
|
|
506
|
+
expect(el.menuIsOpen).to.be.false;
|
|
507
|
+
});
|
|
508
|
+
it("when close=inside , dropdown menu closes only when clicked on menu item", async () => {
|
|
509
|
+
const el = await fixture<SgdsDropdown>(
|
|
510
|
+
html`<sgds-dropdown menuIsOpen close="inside">
|
|
511
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
512
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
513
|
+
</sgds-dropdown> `
|
|
514
|
+
);
|
|
515
|
+
expect(el.menuIsOpen).to.be.true;
|
|
516
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
517
|
+
"show"
|
|
518
|
+
);
|
|
519
|
+
// proving that clicking outside of dropdown menu wont trigger menuclose
|
|
520
|
+
await sendMouse({ type: "click", position: [0, 0] });
|
|
521
|
+
await el.updateComplete;
|
|
522
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
523
|
+
"show"
|
|
524
|
+
);
|
|
525
|
+
expect(el.menuIsOpen).to.be.true;
|
|
526
|
+
const itemOne = el.querySelectorAll(
|
|
527
|
+
"sgds-dropdown-item"
|
|
528
|
+
)[0] as SgdsDropdownItem;
|
|
529
|
+
itemOne.click();
|
|
530
|
+
await el.updateComplete;
|
|
531
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
532
|
+
"show"
|
|
533
|
+
);
|
|
534
|
+
expect(el.menuIsOpen).to.be.false;
|
|
535
|
+
});
|
|
536
|
+
it("when close=outside , dropdown menu closes only when clicked on menu item", async () => {
|
|
537
|
+
const el = await fixture<SgdsDropdown>(
|
|
538
|
+
html`<sgds-dropdown menuIsOpen close="outside">
|
|
539
|
+
<sgds-dropdown-item>slot 1</sgds-dropdown-item>
|
|
540
|
+
<sgds-dropdown-item>slot 2</sgds-dropdown-item>
|
|
541
|
+
</sgds-dropdown> `
|
|
542
|
+
);
|
|
543
|
+
expect(el.menuIsOpen).to.be.true;
|
|
544
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
545
|
+
"show"
|
|
546
|
+
);
|
|
547
|
+
// proving that clicking inside menu item will not close the menu
|
|
548
|
+
const itemOne = el.querySelectorAll(
|
|
549
|
+
"sgds-dropdown-item"
|
|
550
|
+
)[0] as SgdsDropdownItem;
|
|
551
|
+
itemOne.click();
|
|
552
|
+
await el.updateComplete;
|
|
553
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
554
|
+
"show"
|
|
555
|
+
);
|
|
556
|
+
expect(el.menuIsOpen).to.be.true;
|
|
557
|
+
// clicking outside closes the menu
|
|
558
|
+
await sendMouse({ type: "click", position: [0, 0] });
|
|
559
|
+
await el.updateComplete;
|
|
560
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).not.to.have.class(
|
|
561
|
+
"show"
|
|
562
|
+
);
|
|
563
|
+
expect(el.menuIsOpen).to.be.false;
|
|
564
|
+
});
|
|
565
|
+
const closeValues = ["default", "outside", "inside"];
|
|
566
|
+
closeValues.forEach((closeVal) => {
|
|
567
|
+
it(`dropdown menu always closes regardless of prop close value = ${closeVal}`, async () => {
|
|
568
|
+
const el = await fixture<SgdsDropdown>(
|
|
569
|
+
html`<sgds-dropdown menuIsOpen close=${closeVal}>
|
|
570
|
+
<sgds-dropdown-item >slot 1</sgds-dropdown-item>
|
|
571
|
+
<sgds-dropdown-item >slot 2</sgds-dropdown-item>
|
|
572
|
+
</sgds-dropdown> `
|
|
573
|
+
);
|
|
574
|
+
expect(el.menuIsOpen).to.be.true;
|
|
575
|
+
expect(el.shadowRoot?.querySelector("ul.dropdown-menu")).to.have.class(
|
|
576
|
+
"show"
|
|
577
|
+
);
|
|
578
|
+
(el.shadowRoot?.querySelector("sgds-button") as SgdsButton).click();
|
|
579
|
+
// proving that clicking inside menu item will not close the menu
|
|
580
|
+
await el.updateComplete;
|
|
581
|
+
expect(
|
|
582
|
+
el.shadowRoot?.querySelector("ul.dropdown-menu")
|
|
583
|
+
).not.to.have.class("show");
|
|
584
|
+
expect(el.menuIsOpen).to.be.false;
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
})
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
describe("sgds-dropdown-item", () => {
|
|
591
|
+
it("is defined", () => {
|
|
592
|
+
const el = document.createElement("sgds-dropdown-item");
|
|
593
|
+
assert.instanceOf(el, SgdsDropdownItem);
|
|
594
|
+
});
|
|
595
|
+
it("can be semantically compare with shadowDom trees", async () => {
|
|
596
|
+
const el = await fixture<SgdsDropdownItem>(
|
|
597
|
+
html`<sgds-dropdown-item></sgds-dropdown-item>`
|
|
598
|
+
);
|
|
599
|
+
assert.shadowDom.equal(
|
|
600
|
+
el,
|
|
601
|
+
` <li>
|
|
602
|
+
<a
|
|
603
|
+
class="dropdown-item"
|
|
604
|
+
aria-disabled="false"
|
|
605
|
+
href=""
|
|
606
|
+
tabindex="0"
|
|
607
|
+
>
|
|
608
|
+
<slot>
|
|
609
|
+
</slot>
|
|
610
|
+
</a>
|
|
611
|
+
</li>`
|
|
612
|
+
);
|
|
613
|
+
});
|
|
614
|
+
it("href prop is forwarded to a tag href attr", async () => {
|
|
615
|
+
const el = await fixture(
|
|
616
|
+
html`<sgds-dropdown-item href="#">test</sgds-dropdown-item>`
|
|
617
|
+
);
|
|
618
|
+
expect(el.shadowRoot?.querySelector("a")).to.have.attribute("href", "#");
|
|
619
|
+
});
|
|
620
|
+
it("active prop is forwarded to <a> class", async () => {
|
|
621
|
+
const el = await fixture(
|
|
622
|
+
html`<sgds-dropdown-item active>test</sgds-dropdown-item>`
|
|
623
|
+
);
|
|
624
|
+
expect(el.shadowRoot?.querySelector("a")).to.have.class("active");
|
|
625
|
+
});
|
|
626
|
+
it("disabled prop is forwarded to <a> class", async () => {
|
|
627
|
+
const el = await fixture(
|
|
628
|
+
html`<sgds-dropdown-item disabled>test</sgds-dropdown-item>`
|
|
629
|
+
);
|
|
630
|
+
expect(el.shadowRoot?.querySelector("a")).to.have.class("disabled");
|
|
631
|
+
expect(el.shadowRoot?.querySelector("a")).to.have.attribute(
|
|
632
|
+
"aria-disabled",
|
|
633
|
+
"true"
|
|
634
|
+
);
|
|
635
|
+
expect(el.shadowRoot?.querySelector('a')).to.have.attribute('tabindex', '-1')
|
|
636
|
+
});
|
|
637
|
+
})
|