@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.
Files changed (263) hide show
  1. package/.github/workflows/publish-latest.yml +22 -0
  2. package/.github/workflows/publish-pr.yml +28 -0
  3. package/.husky/commit-msg +4 -0
  4. package/.husky/prepare-commit-msg +8 -0
  5. package/.storybook/main.js +16 -0
  6. package/.storybook/preview-head.html +11 -0
  7. package/.storybook/preview.js +9 -0
  8. package/.vscode/settings.json +7 -0
  9. package/CONTRIBUTING.md +56 -0
  10. package/LICENSE +20 -0
  11. package/amplify.yml +22 -0
  12. package/commitlint.config.js +1 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/button-element.scss.html +112 -0
  16. package/coverage/lcov-report/button-element.ts.html +145 -0
  17. package/coverage/lcov-report/favicon.png +0 -0
  18. package/coverage/lcov-report/index.html +116 -0
  19. package/coverage/lcov-report/prettify.css +1 -0
  20. package/coverage/lcov-report/prettify.js +2 -0
  21. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  22. package/coverage/lcov-report/sorter.js +196 -0
  23. package/coverage/lcov.info +32 -0
  24. package/index.html +430 -0
  25. package/{Button → lib/Button}/index.d.ts +0 -0
  26. package/{Button → lib/Button}/index.js +304 -39
  27. package/lib/Button/index.js.map +1 -0
  28. package/{Button → lib/Button}/package.json +0 -0
  29. package/lib/Button/sgds-button.d.ts +48 -0
  30. package/lib/Card/index.d.ts +1 -0
  31. package/lib/Card/index.js +6150 -0
  32. package/lib/Card/index.js.map +1 -0
  33. package/lib/Card/package.json +7 -0
  34. package/lib/Card/sgds-action-card.d.ts +20 -0
  35. package/lib/Checkbox/index.d.ts +1 -0
  36. package/lib/Checkbox/index.js +6366 -0
  37. package/lib/Checkbox/index.js.map +1 -0
  38. package/lib/Checkbox/package.json +7 -0
  39. package/lib/Checkbox/sgds-checkbox.d.ts +36 -0
  40. package/lib/Dropdown/index.d.ts +3 -0
  41. package/{Mainnav → lib/Dropdown}/index.js +2786 -9258
  42. package/lib/Dropdown/index.js.map +1 -0
  43. package/lib/Dropdown/package.json +7 -0
  44. package/lib/Dropdown/sgds-dropdown-item.d.ts +7 -0
  45. package/lib/Dropdown/sgds-dropdown.d.ts +7 -0
  46. package/{Footer → lib/Footer}/index.d.ts +0 -0
  47. package/{Footer → lib/Footer}/index.js +111 -95
  48. package/lib/Footer/index.js.map +1 -0
  49. package/{Footer → lib/Footer}/package.json +0 -0
  50. package/{Footer → lib/Footer}/sgds-footer.d.ts +2 -2
  51. package/lib/Input/index.d.ts +1 -0
  52. package/lib/Input/index.js +6656 -0
  53. package/lib/Input/index.js.map +1 -0
  54. package/lib/Input/package.json +7 -0
  55. package/lib/Input/sgds-input.d.ts +42 -0
  56. package/{Mainnav → lib/Mainnav}/index.d.ts +1 -0
  57. package/{index.js → lib/Mainnav/index.js} +3876 -23415
  58. package/lib/Mainnav/index.js.map +1 -0
  59. package/{Mainnav → lib/Mainnav}/package.json +0 -0
  60. package/lib/Mainnav/sgds-mainnav-dropdown.d.ts +5 -0
  61. package/lib/Mainnav/sgds-mainnav-item.d.ts +4 -0
  62. package/{Mainnav → lib/Mainnav}/sgds-mainnav.d.ts +3 -2
  63. package/{Masthead → lib/Masthead}/index.d.ts +0 -0
  64. package/{Masthead → lib/Masthead}/index.js +140 -114
  65. package/lib/Masthead/index.js.map +1 -0
  66. package/{Masthead → lib/Masthead}/package.json +0 -0
  67. package/{Masthead → lib/Masthead}/sgds-masthead.d.ts +1 -1
  68. package/lib/Modal/index.d.ts +1 -0
  69. package/lib/Modal/index.js +6432 -0
  70. package/lib/Modal/index.js.map +1 -0
  71. package/lib/Modal/package.json +7 -0
  72. package/lib/Modal/sgds-modal.d.ts +28 -0
  73. package/lib/QuantityToggle/index.d.ts +1 -0
  74. package/lib/QuantityToggle/index.js +7049 -0
  75. package/lib/QuantityToggle/index.js.map +1 -0
  76. package/lib/QuantityToggle/package.json +7 -0
  77. package/lib/QuantityToggle/sgds-quantitytoggle.d.ts +30 -0
  78. package/lib/Radio/index.d.ts +2 -0
  79. package/lib/Radio/index.js +12607 -0
  80. package/lib/Radio/index.js.map +1 -0
  81. package/lib/Radio/package.json +7 -0
  82. package/lib/Radio/sgds-radio.d.ts +31 -0
  83. package/lib/Radio/sgds-radiogroup.d.ts +41 -0
  84. package/{Sidenav → lib/Sidenav}/index.d.ts +0 -0
  85. package/{Sidenav → lib/Sidenav}/index.js +2266 -2171
  86. package/lib/Sidenav/index.js.map +1 -0
  87. package/{Sidenav → lib/Sidenav}/package.json +0 -0
  88. package/{Sidenav → lib/Sidenav}/sgds-sidenav-item.d.ts +2 -1
  89. package/lib/Sidenav/sgds-sidenav-link.d.ts +4 -0
  90. package/{Sidenav → lib/Sidenav}/sgds-sidenav.d.ts +1 -1
  91. package/lib/Tab/index.d.ts +3 -0
  92. package/lib/Tab/index.js +13557 -0
  93. package/lib/Tab/index.js.map +1 -0
  94. package/lib/Tab/package.json +7 -0
  95. package/lib/Tab/sgds-tab.d.ts +26 -0
  96. package/lib/Tab/sgds-tabgroup.d.ts +47 -0
  97. package/lib/Tab/sgds-tabpanel.d.ts +25 -0
  98. package/lib/Textarea/index.d.ts +1 -0
  99. package/lib/Textarea/index.js +6696 -0
  100. package/lib/Textarea/index.js.map +1 -0
  101. package/lib/Textarea/package.json +7 -0
  102. package/lib/Textarea/sgds-textarea.d.ts +53 -0
  103. package/lib/index.d.ts +16 -0
  104. package/lib/index.js +134580 -0
  105. package/lib/index.js.map +1 -0
  106. package/lib/umd/index.js +134587 -0
  107. package/lib/umd/index.js.map +1 -0
  108. package/lib/utils/animate.d.ts +10 -0
  109. package/lib/utils/animation-registry.d.ts +18 -0
  110. package/{utils → lib/utils}/breakpoints.d.ts +0 -0
  111. package/lib/utils/card-element.d.ts +11 -0
  112. package/lib/utils/defaultvalue.d.ts +2 -0
  113. package/lib/utils/dropdown-element.d.ts +37 -0
  114. package/lib/utils/event.d.ts +2 -0
  115. package/lib/utils/form.d.ts +38 -0
  116. package/{utils → lib/utils}/generateId.d.ts +0 -0
  117. package/lib/utils/link-element.d.ts +7 -0
  118. package/lib/utils/mergeDeep.d.ts +2 -0
  119. package/lib/utils/modal.d.ts +12 -0
  120. package/lib/utils/object.d.ts +2 -0
  121. package/lib/utils/offset.d.ts +4 -0
  122. package/lib/utils/scroll.d.ts +13 -0
  123. package/{utils → lib/utils}/sgds-element.d.ts +0 -0
  124. package/lib/utils/slot.d.ts +22 -0
  125. package/lib/utils/tabbable.d.ts +8 -0
  126. package/lib/utils/watch.d.ts +14 -0
  127. package/mocks/dropdown.d.ts +4 -0
  128. package/mocks/dropdown.ts +27 -0
  129. package/mocks/link.d.ts +3 -0
  130. package/mocks/link.ts +6 -0
  131. package/package.json +65 -10
  132. package/rollup.config.js +73 -0
  133. package/rollup.test.config.js +42 -0
  134. package/scripts/buildUtils.js +30 -0
  135. package/scripts/frankBuild.js +49 -0
  136. package/src/Button/index.ts +1 -0
  137. package/src/Button/sgds-button.scss +28 -0
  138. package/src/Button/sgds-button.ts +153 -0
  139. package/src/Card/index.ts +1 -0
  140. package/src/Card/sgds-action-card.scss +27 -0
  141. package/src/Card/sgds-action-card.ts +115 -0
  142. package/src/Checkbox/index.ts +1 -0
  143. package/src/Checkbox/sgds-checkbox.scss +4 -0
  144. package/src/Checkbox/sgds-checkbox.ts +149 -0
  145. package/src/Dropdown/index.ts +3 -0
  146. package/src/Dropdown/sgds-dropdown-item.ts +39 -0
  147. package/src/Dropdown/sgds-dropdown.scss +5 -0
  148. package/src/Dropdown/sgds-dropdown.ts +54 -0
  149. package/src/Footer/index.ts +3 -0
  150. package/src/Footer/sgds-footer.scss +5 -0
  151. package/src/Footer/sgds-footer.ts +121 -0
  152. package/src/Input/index.ts +1 -0
  153. package/src/Input/sgds-input.scss +20 -0
  154. package/src/Input/sgds-input.ts +178 -0
  155. package/src/Mainnav/index.ts +4 -0
  156. package/src/Mainnav/sgds-mainnav-dropdown.scss +13 -0
  157. package/src/Mainnav/sgds-mainnav-dropdown.ts +45 -0
  158. package/src/Mainnav/sgds-mainnav-item.scss +24 -0
  159. package/src/Mainnav/sgds-mainnav-item.ts +8 -0
  160. package/src/Mainnav/sgds-mainnav.scss +39 -0
  161. package/src/Mainnav/sgds-mainnav.ts +183 -0
  162. package/src/Masthead/index.ts +1 -0
  163. package/src/Masthead/sgds-masthead.scss +217 -0
  164. package/src/Masthead/sgds-masthead.ts +189 -0
  165. package/src/Modal/index.ts +1 -0
  166. package/src/Modal/sgds-modal.scss +128 -0
  167. package/src/Modal/sgds-modal.ts +309 -0
  168. package/src/QuantityToggle/index.ts +1 -0
  169. package/src/QuantityToggle/sgds-quantitytoggle.scss +10 -0
  170. package/src/QuantityToggle/sgds-quantitytoggle.ts +130 -0
  171. package/src/Radio/index.ts +2 -0
  172. package/src/Radio/sgds-radio.scss +5 -0
  173. package/src/Radio/sgds-radio.ts +120 -0
  174. package/src/Radio/sgds-radiogroup.scss +22 -0
  175. package/src/Radio/sgds-radiogroup.ts +221 -0
  176. package/src/Sidenav/index.ts +4 -0
  177. package/src/Sidenav/sgds-sidenav-item.scss +73 -0
  178. package/src/Sidenav/sgds-sidenav-item.ts +145 -0
  179. package/src/Sidenav/sgds-sidenav-link.scss +25 -0
  180. package/src/Sidenav/sgds-sidenav-link.ts +8 -0
  181. package/src/Sidenav/sgds-sidenav.scss +6 -0
  182. package/src/Sidenav/sgds-sidenav.ts +33 -0
  183. package/src/Tab/index.ts +3 -0
  184. package/src/Tab/sgds-tab.scss +84 -0
  185. package/src/Tab/sgds-tab.ts +87 -0
  186. package/src/Tab/sgds-tabgroup.scss +198 -0
  187. package/src/Tab/sgds-tabgroup.ts +295 -0
  188. package/src/Tab/sgds-tabpanel.scss +12 -0
  189. package/src/Tab/sgds-tabpanel.ts +55 -0
  190. package/src/Textarea/index.ts +1 -0
  191. package/src/Textarea/sgds-textarea.scss +23 -0
  192. package/src/Textarea/sgds-textarea.ts +201 -0
  193. package/src/index.ts +16 -0
  194. package/src/utils/animate.ts +69 -0
  195. package/src/utils/animation-registry.ts +71 -0
  196. package/src/utils/base.scss +14 -0
  197. package/src/utils/breakpoints.ts +5 -0
  198. package/src/utils/card-element.ts +42 -0
  199. package/src/utils/components.style.scss +531 -0
  200. package/src/utils/defaultvalue.ts +51 -0
  201. package/src/utils/dropdown-element.ts +244 -0
  202. package/src/utils/event.ts +13 -0
  203. package/src/utils/form.ts +183 -0
  204. package/src/utils/generateId.ts +4 -0
  205. package/src/utils/link-element.ts +34 -0
  206. package/src/utils/mergeDeep.ts +22 -0
  207. package/src/utils/modal.ts +64 -0
  208. package/src/utils/object.ts +2 -0
  209. package/src/utils/offset.ts +6 -0
  210. package/src/utils/scroll.ts +57 -0
  211. package/src/utils/sgds-element.ts +18 -0
  212. package/src/utils/slot.ts +102 -0
  213. package/src/utils/tabbable.ts +81 -0
  214. package/src/utils/watch.ts +62 -0
  215. package/stories/ActionCard.stories.mdx +199 -0
  216. package/stories/Button.stories.mdx +194 -0
  217. package/stories/Checkbox.stories.mdx +196 -0
  218. package/stories/Dropdown.stories.mdx +152 -0
  219. package/stories/Footer.stories.mdx +261 -0
  220. package/stories/Input.stories.mdx +236 -0
  221. package/stories/MainNav.stories.mdx +169 -0
  222. package/stories/Masthead.stories.mdx +112 -0
  223. package/stories/Modal.stories.mdx +103 -0
  224. package/stories/QuantityToggle.stories.mdx +97 -0
  225. package/stories/Radio.stories.mdx +262 -0
  226. package/stories/Sample.stories.js +29 -0
  227. package/stories/Sample.stories.mdx +33 -0
  228. package/stories/SideNav.stories.mdx +245 -0
  229. package/stories/common.js +185 -0
  230. package/stories/textarea.stories.mdx +253 -0
  231. package/test/button.element.test.ts +185 -0
  232. package/test/checkbox.test.ts +240 -0
  233. package/test/dropdown.test.ts +637 -0
  234. package/test/footer.test.ts +181 -0
  235. package/test/generateId.test.ts +18 -0
  236. package/test/input.element.test.ts +316 -0
  237. package/test/link-element.test.ts +38 -0
  238. package/test/mainnav.test.ts +313 -0
  239. package/test/masthead.test.ts +116 -0
  240. package/test/modal.test.ts +149 -0
  241. package/test/quantitytoggle.test.ts +76 -0
  242. package/test/radio.test.ts +310 -0
  243. package/test/selectable-card.test.ts +159 -0
  244. package/test/sidenav.test.ts +390 -0
  245. package/test/tab.test.ts +76 -0
  246. package/test/textarea.test.ts +126 -0
  247. package/tsconfig.json +26 -0
  248. package/tsconfig.test.json +24 -0
  249. package/typings/scss.d.ts +5 -0
  250. package/web-dev-server.config.mjs +7 -0
  251. package/web-test-runner.config.mjs +47 -0
  252. package/Button/index.js.map +0 -1
  253. package/Button/sgds-button.d.ts +0 -23
  254. package/Footer/index.js.map +0 -1
  255. package/Mainnav/index.js.map +0 -1
  256. package/Mainnav/sgds-mainnav-item.d.ts +0 -7
  257. package/Masthead/index.js.map +0 -1
  258. package/Sidenav/index.js.map +0 -1
  259. package/Sidenav/sgds-sidenav-link.d.ts +0 -7
  260. package/index.d.ts +0 -5
  261. package/index.js.map +0 -1
  262. package/umd/index.js +0 -52092
  263. package/umd/index.js.map +0 -1
@@ -0,0 +1,313 @@
1
+ import { SgdsMainnavItem, SgdsMainnav, SgdsMainnavDropdown } from "../src/Mainnav";
2
+ import "../src/Mainnav";
3
+ import {
4
+ fixture,
5
+ assert,
6
+ expect,
7
+ aTimeout,
8
+ fixtureCleanup,
9
+ } from "@open-wc/testing";
10
+ import { html } from "lit";
11
+
12
+ describe("sgds-mainnav", () => {
13
+ afterEach(() => fixtureCleanup())
14
+ it("is defined", () => {
15
+ const el = document.createElement("sgds-mainnav");
16
+ assert.instanceOf(el, SgdsMainnav);
17
+ });
18
+
19
+ it("can be semantically compare with shadowDom trees", async () => {
20
+ const el = await fixture(
21
+ html`<sgds-mainnav collapseId="collapse-test-id"></sgds-mainnav>`
22
+ );
23
+ assert.shadowDom.equal(
24
+ el,
25
+ `<nav class="navbar navbar-expand-lg navbar-light sgds">
26
+ <a
27
+ class="me-auto navbar-brand order-1"
28
+ href=""
29
+ >
30
+ <slot name="brand">
31
+ </a>
32
+ <slot
33
+ class="order-2"
34
+ name="non-collapsible"
35
+ >
36
+ </slot>
37
+ <button
38
+ aria-controls="collapse-test-id"
39
+ aria-expanded="false"
40
+ aria-label="Toggle navigation"
41
+ class="navbar-toggler order-3"
42
+ type="button"
43
+ >
44
+ <svg
45
+ xmlns="http://www.w3.org/2000/svg"
46
+ width="30"
47
+ height="30"
48
+ fill="currentColor"
49
+ class="bi bi-list"
50
+ viewBox="0 0 16 16"
51
+ >
52
+ <path
53
+ fill-rule="evenodd"
54
+ d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"
55
+ />
56
+ </svg>
57
+ </button>
58
+ <div
59
+ class="collapse navbar-collapse order-4"
60
+ id="collapse-test-id"
61
+ >
62
+ <ul class="navbar-nav">
63
+ <slot>
64
+ </slot>
65
+ <slot name="end">
66
+ </slot>
67
+ </ul>
68
+ </div>
69
+ `
70
+ );
71
+ });
72
+
73
+ it("brandHref props forwards to a.navbar-brand href attribute", async () => {
74
+ const el = await fixture(
75
+ html`<sgds-mainnav brandHref="test"></sgds-mainnav>`
76
+ );
77
+ expect(
78
+ el.shadowRoot?.querySelector("a.navbar-brand")?.getAttribute("href")
79
+ ).to.equal("test");
80
+ });
81
+
82
+ it("when mode is offcanvas, offcanvas classes are present instead of collapse classes", async () => {
83
+ const el = await fixture(
84
+ html`<sgds-mainnav mode="offcanvas"></sgds-mainnav>`
85
+ );
86
+ expect(el.shadowRoot?.querySelector(".offcanvas.offcanvas-start.order-4"))
87
+ .to.exist;
88
+ expect(el.shadowRoot?.querySelector(".collapse.navbar-collapse.order-4"))
89
+ .not.to.exist;
90
+ });
91
+
92
+ it("when expand=always, nav class has .navbar-expand", async () => {
93
+ const el = await fixture(
94
+ html`<sgds-mainnav expand="always"></sgds-mainnav>`
95
+ );
96
+ expect(el.shadowRoot?.querySelector("nav.sgds.navbar")).to.have.class(
97
+ "navbar-expand"
98
+ );
99
+ const classList =
100
+ el.shadowRoot?.querySelector("nav.sgds.navbar")?.classList.value;
101
+ expect(/navbar-expand/.test(classList!)).to.be.true;
102
+ });
103
+ it("when expand=never, nav class does not have .navbar-expand", async () => {
104
+ const el = await fixture(
105
+ html`<sgds-mainnav expand="never"></sgds-mainnav>`
106
+ );
107
+ const classList =
108
+ el.shadowRoot?.querySelector("nav.sgds.navbar")?.classList.value;
109
+ expect(/navbar-expand/.test(classList!)).to.be.false;
110
+ });
111
+ const testSizes = ["sm", "md", "lg", "xl", "xxl"];
112
+ testSizes.forEach((size) => {
113
+ it(`when expand=${size}, nav class have .navbar-expand=${size}`, async () => {
114
+ const el = await fixture(
115
+ html`<sgds-mainnav expand=${size}></sgds-mainnav>`
116
+ );
117
+ const classList =
118
+ el.shadowRoot?.querySelector("nav.sgds.navbar")?.classList.value;
119
+ expect(/navbar-expand/.test(classList!)).to.be.true;
120
+ expect(classList).to.contain(`navbar-expand-${size}`);
121
+ });
122
+ });
123
+
124
+ it("in default mode (collapse menu), when .navbar-toggler is clicked .navbar-collapse has .show class and toggler has aria-expanded true", async () => {
125
+ const el = await fixture(
126
+ html`<sgds-mainnav expand="never"></sgds-mainnav>`
127
+ );
128
+ const mainNavCollapse = el.shadowRoot?.querySelector(".navbar-collapse");
129
+ expect(mainNavCollapse).not.to.have.class("show");
130
+ const toggler = el.shadowRoot?.querySelector(
131
+ "button.navbar-toggler"
132
+ ) as HTMLButtonElement;
133
+ expect(toggler.getAttribute('aria-expanded')).to.equal('false')
134
+ toggler?.click();
135
+ expect(mainNavCollapse).to.have.class("collapsing");
136
+ await aTimeout(500);
137
+ expect(mainNavCollapse).to.have.class("show");
138
+ expect(toggler.getAttribute('aria-expanded')).to.equal('true')
139
+ toggler?.click();
140
+ await aTimeout(500);
141
+ expect(mainNavCollapse).not.to.have.class("show");
142
+ expect(toggler.getAttribute('aria-expanded')).to.equal('false')
143
+ });
144
+ // initial window.innerWidth = 800
145
+ // LG_BREAKPOINT = 992
146
+ // since window.innerWidth < LG_BREAKPOINT --> expect non-collapsible slot to be .order-2 (see first test)
147
+ it('when expand=lg and window resize event occurs to above breakpoint, it changes order of non-collapsible slot, and end slot has class .slot-end', async() => {
148
+ const el = await fixture<SgdsMainnav>(
149
+ html`<sgds-mainnav expand="lg"></sgds-mainnav>`
150
+ );
151
+ expect(el.shadowRoot?.querySelector("slot[name='non-collapsible']")).to.have.class('order-2')
152
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).not.to.have.class('slot-end')
153
+ Object.defineProperty(window, 'innerWidth', {
154
+ writable: true,
155
+ configurable: true,
156
+ value: 1000, // value above LG_BREAKPOINT
157
+ })
158
+ window.dispatchEvent(new Event('resize'));
159
+ await el.updateComplete
160
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-5')
161
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).to.have.class('slot-end')
162
+
163
+ })
164
+ //SM_BREAKPOINT = 576
165
+ // now window.innerWidth = 1000
166
+ it('when expand=sm and window resize event occurs to above breakpoint, it changes order of non-collapsible slot and end slot has class slot-end ', async() => {
167
+ const el = await fixture<SgdsMainnav>(
168
+ html`<sgds-mainnav expand="sm"></sgds-mainnav>`
169
+ );
170
+ expect(el.shadowRoot?.querySelector("slot[name='non-collapsible']")).to.have.class('order-5')
171
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).to.have.class('slot-end')
172
+ Object.defineProperty(window, 'innerWidth', {
173
+ writable: true,
174
+ configurable: true,
175
+ value: 576-1, // value below SM_BREAKPOINT
176
+ })
177
+ window.dispatchEvent(new Event('resize'));
178
+ await el.updateComplete
179
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-2')
180
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).not.to.have.class('slot-end')
181
+
182
+ })
183
+ // now window.innerWidth = 575
184
+ it('when expand=always and window resize event occurs, it NEVER changes order of non-collapsible slot and end slot ALWAYS have slot-end ', async() => {
185
+ const el = await fixture<SgdsMainnav>(
186
+ html`<sgds-mainnav expand="always"></sgds-mainnav>`
187
+ );
188
+ expect(el.shadowRoot?.querySelector("slot[name='non-collapsible']")).to.have.class('order-5')
189
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).to.have.class('slot-end')
190
+
191
+ Object.defineProperty(window, 'innerWidth', {
192
+ writable: true,
193
+ configurable: true,
194
+ value: 1, // trying extreme sizes
195
+ })
196
+ window.dispatchEvent(new Event('resize'));
197
+ await el.updateComplete
198
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-5')
199
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).to.have.class('slot-end')
200
+
201
+
202
+ Object.defineProperty(window, 'innerWidth', {
203
+ writable: true,
204
+ configurable: true,
205
+ value: 100000, // trying extreme sizes
206
+ })
207
+ window.dispatchEvent(new Event('resize'));
208
+ await el.updateComplete
209
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-5')
210
+ })
211
+ it('when expand=never and window resize event occurs, it NEVER changes order of non-collapsible slot, and end slot NEVER has class slot-end', async() => {
212
+ const el = await fixture<SgdsMainnav>(
213
+ html`<sgds-mainnav expand="never"></sgds-mainnav>`
214
+ );
215
+ expect(el.shadowRoot?.querySelector("slot[name='non-collapsible']")).to.have.class('order-2')
216
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).not.to.have.class('slot-end')
217
+
218
+ Object.defineProperty(window, 'innerWidth', {
219
+ writable: true,
220
+ configurable: true,
221
+ value: 1, // trying extreme sizes
222
+ })
223
+ window.dispatchEvent(new Event('resize'));
224
+ await el.updateComplete
225
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-2')
226
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).not.to.have.class('slot-end')
227
+
228
+ Object.defineProperty(window, 'innerWidth', {
229
+ writable: true,
230
+ configurable: true,
231
+ value: 100000, // trying extreme sizes
232
+ })
233
+ window.dispatchEvent(new Event('resize'));
234
+ await el.updateComplete
235
+ expect(el.shadowRoot?.querySelector('slot[name="non-collapsible"]')).to.have.class('order-2')
236
+ expect(el.shadowRoot?.querySelector("slot[name='end']")).not.to.have.class('slot-end')
237
+
238
+ })
239
+
240
+ // it('keyboard esc to exit offcanvas works', async() => {
241
+ // const el = await fixture<SgdsMainnav>(
242
+ // html`<sgds-mainnav expand="never" mode="offcanvas"></sgds-mainnav>`
243
+ // );
244
+ // el.shadowRoot?.querySelector('button')?.click()
245
+ // await el.updateComplete
246
+ // expect(el.shadowRoot?.querySelector(".offcanvas.show")).to.exist
247
+
248
+ // el.dispatchEvent(new KeyboardEvent("keydown", {key: "Escape"}))
249
+ // await el.updateComplete
250
+ // expect(el.shadowRoot?.querySelector('.offcanvas')).not.to.have.class('show')
251
+
252
+ // })
253
+ it('adds name attribute to elements in slot="end" only', async() => {
254
+ const el = await fixture<SgdsMainnav>(
255
+ html`<sgds-mainnav>
256
+ <div></div>
257
+ <sgds-mainnav-item slot="end"></sgds-mainnav-item>
258
+ <sgds-button slot="end"></sgds-button>
259
+ </sgds-mainnav>`
260
+ );
261
+ expect(el.querySelector('div')).not.to.have.attribute('name', 'div')
262
+ expect(el.querySelector('sgds-mainnav-item')).to.have.attribute('name', 'sgds-mainnav-item')
263
+ expect(el.querySelector('sgds-button')).to.have.attribute('name', 'sgds-button')
264
+
265
+ })
266
+ });
267
+
268
+ describe('sgds-mainnav-item', () => {
269
+ it("is defined", () => {
270
+ const el = document.createElement("sgds-mainnav-item");
271
+ assert.instanceOf(el, SgdsMainnavItem);
272
+ });
273
+ })
274
+
275
+ describe('sgds-mainnav-dropdown', () => {
276
+ it("is defined", () => {
277
+ const el = document.createElement("sgds-mainnav-dropdown");
278
+ assert.instanceOf(el, SgdsMainnavDropdown);
279
+ });
280
+ it("can be semantically compare with shadowDom trees", async () => {
281
+ const el = await fixture(html`<sgds-mainnav-dropdown togglerId="test-dropdown" togglerText="test"></sgds-mainnav-dropdown>`);
282
+ assert.shadowDom.equal(
283
+ el,
284
+ ` <li class="nav-item">
285
+ <a
286
+ class="nav-link"
287
+ aria-expanded="false"
288
+ id="test-dropdown"
289
+ tabindex="0"
290
+ role="button"
291
+ >
292
+ test
293
+ <svg
294
+ xmlns="http://www.w3.org/2000/svg"
295
+ width="16"
296
+ height="16"
297
+ fill="currentColor"
298
+ class="bi bi-chevron-down"
299
+ viewBox="0 0 16 16"
300
+ >
301
+ <path
302
+ fill-rule="evenodd"
303
+ 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"
304
+ />
305
+ </svg>
306
+ </a>
307
+ <ul class="dropdown-menu" role="menu" part="menu">
308
+ <slot></slot>
309
+ </ul>
310
+ </li>`
311
+ );
312
+ });
313
+ })
@@ -0,0 +1,116 @@
1
+ import { SgdsMasthead } from "../src/Masthead";
2
+ import "../src/Masthead/sgds-masthead";
3
+ import { fixture, assert, expect, elementUpdated } from "@open-wc/testing";
4
+ import { html } from "lit";
5
+
6
+ describe("sgds-masthead", () => {
7
+ it("is defined", () => {
8
+ const el = document.createElement("sgds-masthead");
9
+ assert.instanceOf(el, SgdsMasthead);
10
+ });
11
+
12
+
13
+
14
+ it("renders with default values", async () => {
15
+ const el = await fixture(html`<sgds-masthead></sgds-masthead>`);
16
+ assert.shadowDom.equal(
17
+ el,
18
+ `
19
+ <div id="sgds-masthead" class="sgds-masthead" aria-label="A Singapore Government Agency Website">
20
+ <div class="container">
21
+ <div class="row">
22
+ <div class="col">
23
+ <div class="masthead-layout">
24
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" class="sg-crest">
25
+ <title>sg-crest</title>
26
+ <path d="M5.896 11.185c0 0-0.949 1.341 0.294 3.075 0 0 0.196-0.883 2.159-0.883h2.356c2.225 0 3.893-2.126 2.846-4.319 0 0 1.57 0.164 2.095-0.818 0.523-0.981-0.033-1.374-0.818-1.374h-3.959c0 0.704-1.341 0.802-1.341 0h-2.225c0 0-1.669 0-1.701 1.407 0 0 0.377-0.229 0.752-0.261v0.375c0 0-0.458 0.082-0.671 0.197-0.212 0.114-0.523 0.425-0.228 1.227 0.294 0.801 0.409 1.079 0.409 1.079s0.475-0.41 1.244-0.41h0.9c1.602 0 1.308 1.554-0.295 1.554s-1.815-0.85-1.815-0.85z"></path>
27
+ <path d="M14.255 9.566c0 0 0.54 0.033 0.932-0.31 0 0 3.55 2.765-1.717 8.326-5.268 5.562-1.195 9.162-1.195 9.162s-0.948 0.915-0.409 2.699c0 0-2.191-1.237-3.867-3.338-2.422-3.036-3.902-7.681 2.749-11.386 0 0 4.389-2.208 3.506-5.153z"></path>
28
+ <path d="M8.829 6.343c0 0 0.709-1.265 2.355-1.265 1.298 0 1.594-0.666 1.594-0.666s0.566-1.079 3.424-1.079c2.619 0 4.384 0.873 5.812 2.039 0 0-3.85-2.388-7.645 0.971h-5.54z"></path>
29
+ <path d="M24.839 14.348c-0.109-3.948-3.163-8.179-9.728-7.939 6.413-5.431 17.537 6.695 8.375 13.066 0 0 1.533-2.186 1.353-5.126z"></path>
30
+ <path d="M16.093 6.845c8.005-0.24 10.863 9.357 5.693 13.676l-5.191 2.509c0 0-0.676-2.181 1.833-4.734 2.509-2.551 4.929-7.328-2.006-10.469 0 0 0.131-0.654-0.327-0.981z"></path>
31
+ <path d="M15.678 9.004c0 0 0.393-0.371 0.524-0.676 5.954 2.486 5.017 6.697 1.461 10.23-2.181 2.246-1.505 4.668-1.505 4.668s-2.66 1.657-3.577 3.097c0 0-3.852-3.28 1.483-8.724 5.235-5.344 1.614-8.594 1.614-8.594z"></path>
32
+ </svg>
33
+ <span>A Singapore Government Agency Website</span>
34
+ <div class="sgds-masthead-button" id="sgds-masthead-identify" role="button" aria-controls="sgds-masthead-content" aria-expanded="false">
35
+ <span class="sgds-masthead-button-text">How to identify</span>
36
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" class="sgds-masthead-identify-icon open">
37
+ <path d="M8.65188 6.85L8.64813 6.84625L10.0031 5.49125L17.0744 12.5625L15.7194 13.9175L10.0075 8.20562L4.2875 13.9256L2.9325 12.5706L8.6525 6.85062L8.65188 6.85Z" fill="#2F60CE"></path>
38
+ </svg>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ <div id="sgds-masthead-content" class="container sgds-masthead-content ">
45
+ <div class="row">
46
+ <div class="col">
47
+ <div class="content-grid">
48
+ <div class="wrapper">
49
+ <div class="icon">
50
+ <svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 17 17" fill="none" class="banner-icon">
51
+ <path d="M0.166016 5.6665V9.00067H0.999349V13.9998H0.166016V16.4998H0.999349H3.49935H5.16602H7.66601H9.33268H11.8327H13.4993L15.9993 16.5007V16.4998H16.8327V13.9998H15.9993V9.00067H16.8327V5.6665L8.49935 0.666504L0.166016 5.6665ZM3.49935 13.9998V9.00067H5.16602V13.9998H3.49935ZM7.66601 13.9998V9.00067H9.33268V13.9998H7.66601ZM13.4993 13.9998H11.8327V9.00067H13.4993V13.9998ZM10.166 5.6665C10.166 6.58651 9.41935 7.33317 8.49935 7.33317C7.57935 7.33317 6.83268 6.58651 6.83268 5.6665C6.83268 4.7465 7.57935 3.99984 8.49935 3.99984C9.41935 3.99984 10.166 4.7465 10.166 5.6665Z" fill="#242425"></path>
52
+ </svg>
53
+ </div>
54
+ <div class="content">
55
+ <div class="title">
56
+ Official website links end with .gov.sg
57
+ </div>
58
+ <article>
59
+ Government agencies communicate via .gov.sg websites (e.g.
60
+ go.gov.sg/open).
61
+ <a href="https://www.gov.sg/trusted-sites#govsites" class="trusted-websites-link" rel="noreferrer" target="_blank">Trusted websites<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 32 32" class="trusted-websites-icon">
62
+ <title>Trusted websites</title>
63
+ <path d="M18.667 4v2.667h4c0.186-0.020 0.374-0.020 0.56 0l-2.667 2.667-6.973 6.987 1.88 1.88 9.733-9.667c0.092 0.257 0.137 0.528 0.133 0.8v4h2.667v-9.333h-9.333z"></path>
64
+ <path d="M22.667 25.333h-16v-16h8v-2.667h-8c-1.473 0-2.667 1.194-2.667 2.667v16c0 1.473 1.194 2.667 2.667 2.667h16c1.473 0 2.667-1.194 2.667-2.667v-8h-2.667v8z"></path></svg></a>
65
+ </article>
66
+ </div>
67
+ </div>
68
+ <div class="wrapper">
69
+ <div class="icon">
70
+ <svg xmlns="http://www.w3.org/2000/svg" width="15" height="18" viewBox="0 0 15 18" fill="none" class="banner-icon">
71
+ <path d="M14.1663 9.00008C14.1663 8.08091 13.4188 7.33342 12.4997 7.33342H11.6663V4.83342C11.6663 2.53591 9.79717 0.666748 7.49967 0.666748C5.20217 0.666748 3.33301 2.53591 3.33301 4.83342V7.33342H2.49967C1.58051 7.33342 0.833008 8.08091 0.833008 9.00008V15.6667C0.833008 16.5859 1.58051 17.3334 2.49967 17.3334H12.4997C13.4188 17.3334 14.1663 16.5859 14.1663 15.6667V9.00008ZM4.99967 4.83342C4.99967 3.45508 6.12134 2.33341 7.49967 2.33341C8.87801 2.33341 9.99967 3.45508 9.99967 4.83342V7.33342H4.99967V4.83342Z" fill="#242425"></path>
72
+ </svg>
73
+ </div>
74
+ <div class="content">
75
+ <div class="title">Secure websites use HTTPS</div>
76
+ <article>
77
+ Look for a<b> lock </b>(<svg xmlns="http://www.w3.org/2000/svg" width="15" height="18" viewBox="0 0 15 18" fill="none" class="banner-icon-inline">
78
+ <path d="M14.1663 9.00008C14.1663 8.08091 13.4188 7.33342 12.4997 7.33342H11.6663V4.83342C11.6663 2.53591 9.79717 0.666748 7.49967 0.666748C5.20217 0.666748 3.33301 2.53591 3.33301 4.83342V7.33342H2.49967C1.58051 7.33342 0.833008 8.08091 0.833008 9.00008V15.6667C0.833008 16.5859 1.58051 17.3334 2.49967 17.3334H12.4997C13.4188 17.3334 14.1663 16.5859 14.1663 15.6667V9.00008ZM4.99967 4.83342C4.99967 3.45508 6.12134 2.33341 7.49967 2.33341C8.87801 2.33341 9.99967 3.45508 9.99967 4.83342V7.33342H4.99967V4.83342Z" fill="#242425"></path></svg>) or https:// as an added precaution. Share sensitive
79
+ information only on official, secure websites.
80
+ </article>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ `
89
+ );
90
+ });
91
+
92
+ it("when clicked on #sgds-masthead-identify, shows #sgds-masthead-content", async () => {
93
+ const el = await fixture<SgdsMasthead>(html`<sgds-masthead></sgds-masthead>`);
94
+ expect(
95
+ el.shadowRoot?.getElementById("sgds-masthead-content")?.classList.value
96
+ ).not.to.contain("show");
97
+ el.shadowRoot?.getElementById("sgds-masthead-identify")?.click();
98
+ await elementUpdated(el);
99
+ expect(
100
+ el.shadowRoot?.getElementById("sgds-masthead-content")
101
+ ).to.have.class("show");
102
+ });
103
+
104
+ it("when fluid attriubute is inserted, .container class should update to .container-fluid", async () => {
105
+ const el = await fixture<SgdsMasthead>(html`<sgds-masthead></sgds-masthead>`);
106
+ const containerWrapper = el.shadowRoot?.getElementById("sgds-masthead")?.children[0]
107
+ expect(
108
+ containerWrapper?.classList.value
109
+ ).to.contain("container");
110
+ el.setAttribute("fluid","")
111
+ await elementUpdated(el);
112
+ expect(
113
+ containerWrapper?.classList.value
114
+ ).to.contain("container-fluid");
115
+ });
116
+ });
@@ -0,0 +1,149 @@
1
+ import { SgdsModal } from '../src/Modal/sgds-modal'
2
+ import '../src/Modal/sgds-modal';
3
+ import { expect, fixture, waitUntil } from '@open-wc/testing';
4
+ import { sendKeys } from '@web/test-runner-commands';
5
+ import sinon from 'sinon';
6
+ import { html } from "lit";
7
+
8
+ describe('<sgds-modal>', () => {
9
+ it('should be visible with the open attribute', async () => {
10
+ const el = await fixture<SgdsModal>(html`
11
+ <sgds-modal open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
12
+ `);
13
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
14
+
15
+ expect(base.hidden).to.be.false;
16
+ });
17
+
18
+ it('should not be visible without the open attribute', async () => {
19
+ const el = await fixture<SgdsModal>(
20
+ html` <sgds-modal>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal> `
21
+ );
22
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
23
+
24
+ expect(base.hidden).to.be.true;
25
+ });
26
+
27
+ it('should emit sgds-show and sgds-after-show when calling show()', async () => {
28
+ const el = await fixture<SgdsModal>(html`
29
+ <sgds-modal>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
30
+ `);
31
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
32
+ const showHandler = sinon.spy();
33
+ const afterShowHandler = sinon.spy();
34
+
35
+ el.addEventListener('sgds-show', showHandler);
36
+ el.addEventListener('sgds-after-show', afterShowHandler);
37
+ el.show();
38
+
39
+ await waitUntil(() => showHandler.calledOnce);
40
+ await waitUntil(() => afterShowHandler.calledOnce);
41
+
42
+ expect(showHandler).to.have.been.calledOnce;
43
+ expect(afterShowHandler).to.have.been.calledOnce;
44
+ expect(base.hidden).to.be.false;
45
+ });
46
+
47
+ it('should emit sgds-hide and sgds-after-hide when calling hide()', async () => {
48
+ const el = await fixture<SgdsModal>(html`
49
+ <sgds-modal open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
50
+ `);
51
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
52
+ const hideHandler = sinon.spy();
53
+ const afterHideHandler = sinon.spy();
54
+
55
+ el.addEventListener('sgds-hide', hideHandler);
56
+ el.addEventListener('sgds-after-hide', afterHideHandler);
57
+ el.hide();
58
+
59
+ await waitUntil(() => hideHandler.calledOnce);
60
+ await waitUntil(() => afterHideHandler.calledOnce);
61
+
62
+ expect(hideHandler).to.have.been.calledOnce;
63
+ expect(afterHideHandler).to.have.been.calledOnce;
64
+ expect(base.hidden).to.be.true;
65
+ });
66
+
67
+ it('should emit sgds-show and sgds-after-show when setting open = true', async () => {
68
+ const el = await fixture<SgdsModal>(html`
69
+ <sgds-modal>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
70
+ `);
71
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
72
+ const showHandler = sinon.spy();
73
+ const afterShowHandler = sinon.spy();
74
+
75
+ el.addEventListener('sgds-show', showHandler);
76
+ el.addEventListener('sgds-after-show', afterShowHandler);
77
+ el.open = true;
78
+
79
+ await waitUntil(() => showHandler.calledOnce);
80
+ await waitUntil(() => afterShowHandler.calledOnce);
81
+
82
+ expect(showHandler).to.have.been.calledOnce;
83
+ expect(afterShowHandler).to.have.been.calledOnce;
84
+ expect(base.hidden).to.be.false;
85
+ });
86
+
87
+ it('should emit sgds-hide and sgds-after-hide when setting open = false', async () => {
88
+ const el = await fixture<SgdsModal>(html`
89
+ <sgds-modal open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
90
+ `);
91
+ const base = el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
92
+ const hideHandler = sinon.spy();
93
+ const afterHideHandler = sinon.spy();
94
+
95
+ el.addEventListener('sgds-hide', hideHandler);
96
+ el.addEventListener('sgds-after-hide', afterHideHandler);
97
+ el.open = false;
98
+
99
+ await waitUntil(() => hideHandler.calledOnce);
100
+ await waitUntil(() => afterHideHandler.calledOnce);
101
+
102
+ expect(hideHandler).to.have.been.calledOnce;
103
+ expect(afterHideHandler).to.have.been.calledOnce;
104
+ expect(base.hidden).to.be.true;
105
+ });
106
+
107
+ it('should not close when sgds-request-close is prevented', async () => {
108
+ const el = await fixture<SgdsModal>(html`
109
+ <sgds-modal open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</sgds-modal>
110
+ `);
111
+ const overlay = el.shadowRoot!.querySelector<HTMLElement>('[part="overlay"]')!;
112
+
113
+ el.addEventListener('sgds-request-close', event => {
114
+ event.preventDefault();
115
+ });
116
+ overlay.click();
117
+
118
+ expect(el.open).to.be.true;
119
+ });
120
+
121
+ it('should allow initial focus to be set', async () => {
122
+ const el = await fixture<SgdsModal>(html` <sgds-modal><input /></sgds-modal> `);
123
+ const input = el.querySelector('input')!;
124
+ const initialFocusHandler = sinon.spy((event: Event) => {
125
+ event.preventDefault();
126
+ input.focus();
127
+ });
128
+
129
+ el.addEventListener('sgds-initial-focus', initialFocusHandler);
130
+ el.show();
131
+
132
+ await waitUntil(() => initialFocusHandler.calledOnce);
133
+
134
+ expect(initialFocusHandler).to.have.been.calledOnce;
135
+ expect(document.activeElement).to.equal(input);
136
+ });
137
+
138
+ it('should close when pressing Escape', async () => {
139
+ const el = await fixture<SgdsModal>(html` <sgds-modal open></sgds-modal> `);
140
+ const hideHandler = sinon.spy();
141
+
142
+ el.addEventListener('sgds-hide', hideHandler);
143
+
144
+ await sendKeys({ press: 'Escape' });
145
+ await waitUntil(() => hideHandler.calledOnce);
146
+
147
+ expect(el.open).to.be.false;
148
+ });
149
+ });
@@ -0,0 +1,76 @@
1
+ import { SgdsQuantityToggle } from '../src/QuantityToggle/sgds-quantitytoggle';
2
+ import '../src/QuantityToggle/sgds-quantitytoggle';
3
+ import {fixture, assert, expect, aTimeout, waitUntil} from '@open-wc/testing';
4
+ import {html} from 'lit';
5
+ import sinon from 'sinon';
6
+ import { sendKeys } from "@web/test-runner-commands";
7
+ import { SgdsButton } from '../src/Button';
8
+
9
+ describe('sgds-quantitytoggle', () => {
10
+ it('is defined', () => {
11
+ const el = document.createElement('sgds-quantitytoggle');
12
+ assert.instanceOf(el, SgdsQuantityToggle)
13
+ })
14
+ });
15
+
16
+ describe('when minusBtn or plusBtn is clicked', () => {
17
+
18
+ it('should decrease and increase the count by 1 respectively', async () => {
19
+ const el = await fixture<SgdsQuantityToggle>(html`<sgds-quantitytoggle count="10"></sgds-quantitytoggle>`);
20
+ const minusBtn = el.shadowRoot?.querySelector('.button-group_button-first') as SgdsButton;
21
+ const plusBtn = el.shadowRoot?.querySelector('.button-group_button-last') as SgdsButton;
22
+ const inputEl = el.shadowRoot?.querySelector('.form-control');
23
+
24
+ const minusclickHandler = sinon.spy();
25
+ el.addEventListener('click', minusclickHandler);
26
+ minusBtn.click()
27
+ await waitUntil(() => minusclickHandler.calledOnce);
28
+
29
+ expect(el.count).to.equal(9);
30
+
31
+ const plusclickHandler = sinon.spy();
32
+ el.addEventListener('click', plusclickHandler);
33
+ plusBtn.click()
34
+ await waitUntil(() => plusclickHandler.calledOnce);
35
+
36
+ expect(el.count).to.equal(10);
37
+ })
38
+
39
+
40
+ });
41
+
42
+ describe('when count change', ()=> {
43
+ it("fires sgds-input event when value is entered", async () => {
44
+ const el = await fixture<SgdsQuantityToggle>(html`<sgds-quantitytoggle count="10"></sgds-quantitytoggle>`);
45
+ const inputEl = el.shadowRoot?.querySelector('input.form-control') as HTMLInputElement;
46
+ const inputHandler = sinon.spy();
47
+ inputEl.focus();
48
+ el.addEventListener("sgds-input", inputHandler);
49
+ await sendKeys({ press: "0" });
50
+ waitUntil(() => inputHandler.calledOnce);
51
+ expect(inputHandler).to.have.been.calledOnce;
52
+ });
53
+ })
54
+
55
+ describe('when step', ()=> {
56
+ it("should decrease and increase with steps", async () => {
57
+ const el = await fixture<SgdsQuantityToggle>(html`<sgds-quantitytoggle count="10" step="91"></sgds-quantitytoggle>`);
58
+ const minusBtn = el.shadowRoot?.querySelector('.button-group_button-first') as SgdsButton;
59
+ const plusBtn = el.shadowRoot?.querySelector('.button-group_button-last') as SgdsButton;
60
+ const inputEl = el.shadowRoot?.querySelector('.form-control');
61
+
62
+ const minusclickHandler = sinon.spy();
63
+ el.addEventListener('click', minusclickHandler);
64
+ minusBtn.click()
65
+ await waitUntil(() => minusclickHandler.calledOnce);
66
+
67
+ expect(el.count).to.equal(0);
68
+
69
+ const plusclickHandler = sinon.spy();
70
+ el.addEventListener('click', plusclickHandler);
71
+ plusBtn.click()
72
+ await waitUntil(() => plusclickHandler.calledOnce);
73
+
74
+ expect(el.count).to.equal(91);
75
+ })
76
+ });