@statistikzh/leu 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/.github/workflows/deploy-github-pages.yaml +33 -0
  2. package/.storybook/main.js +27 -1
  3. package/.storybook/manager-head.html +1 -0
  4. package/.storybook/manager.js +9 -0
  5. package/.storybook/preview-head.html +1 -1
  6. package/.storybook/preview.js +59 -6
  7. package/.storybook/static/logo.svg +19 -0
  8. package/.storybook/theme.js +7 -0
  9. package/CHANGELOG.md +54 -0
  10. package/README.md +1 -1
  11. package/custom-elements-manifest.config.js +46 -0
  12. package/dist/Accordion.d.ts +31 -0
  13. package/dist/Accordion.d.ts.map +1 -0
  14. package/dist/Accordion.js +257 -0
  15. package/dist/Breadcrumb.d.ts +69 -0
  16. package/dist/Breadcrumb.d.ts.map +1 -0
  17. package/dist/Breadcrumb.js +392 -0
  18. package/dist/Button-da11d064.d.ts +84 -0
  19. package/dist/Button-da11d064.d.ts.map +1 -0
  20. package/dist/Button-da11d064.js +542 -0
  21. package/dist/Button.d.ts +2 -0
  22. package/dist/Button.d.ts.map +1 -0
  23. package/dist/Button.js +6 -423
  24. package/dist/ButtonGroup.d.ts +24 -0
  25. package/dist/ButtonGroup.d.ts.map +1 -0
  26. package/dist/ButtonGroup.js +72 -43
  27. package/dist/Checkbox.d.ts +13 -0
  28. package/dist/Checkbox.d.ts.map +1 -0
  29. package/dist/Checkbox.js +101 -84
  30. package/dist/CheckboxGroup.d.ts +13 -0
  31. package/dist/CheckboxGroup.d.ts.map +1 -0
  32. package/dist/CheckboxGroup.js +41 -37
  33. package/dist/Chip.d.ts +5 -0
  34. package/dist/Chip.d.ts.map +1 -0
  35. package/dist/{Chip-5f70d04f.js → Chip.js} +21 -6
  36. package/dist/ChipGroup.d.ts +28 -0
  37. package/dist/ChipGroup.d.ts.map +1 -0
  38. package/dist/ChipGroup.js +64 -10
  39. package/dist/ChipLink.d.ts +15 -0
  40. package/dist/ChipLink.d.ts.map +1 -0
  41. package/dist/ChipLink.js +4 -7
  42. package/dist/ChipRemovable.d.ts +13 -0
  43. package/dist/ChipRemovable.d.ts.map +1 -0
  44. package/dist/ChipRemovable.js +5 -8
  45. package/dist/ChipSelectable.d.ts +22 -0
  46. package/dist/ChipSelectable.d.ts.map +1 -0
  47. package/dist/ChipSelectable.js +8 -11
  48. package/dist/Dropdown.d.ts +15 -0
  49. package/dist/Dropdown.d.ts.map +1 -0
  50. package/dist/Dropdown.js +73 -26
  51. package/dist/Input.d.ts +154 -0
  52. package/dist/Input.d.ts.map +1 -0
  53. package/dist/Input.js +42 -35
  54. package/dist/Menu.d.ts +8 -0
  55. package/dist/Menu.d.ts.map +1 -0
  56. package/dist/Menu.js +2 -5
  57. package/dist/MenuItem.d.ts +21 -0
  58. package/dist/MenuItem.d.ts.map +1 -0
  59. package/dist/MenuItem.js +32 -17
  60. package/dist/Pagination.d.ts +27 -0
  61. package/dist/Pagination.d.ts.map +1 -0
  62. package/dist/Pagination.js +121 -89
  63. package/dist/Popup.d.ts +18 -0
  64. package/dist/Popup.d.ts.map +1 -0
  65. package/dist/Popup.js +215 -0
  66. package/dist/Radio.d.ts +12 -0
  67. package/dist/Radio.d.ts.map +1 -0
  68. package/dist/Radio.js +9 -8
  69. package/dist/RadioGroup.d.ts +20 -0
  70. package/dist/RadioGroup.d.ts.map +1 -0
  71. package/dist/RadioGroup.js +41 -39
  72. package/dist/ScrollTop.d.ts +19 -0
  73. package/dist/ScrollTop.d.ts.map +1 -0
  74. package/dist/ScrollTop.js +122 -0
  75. package/dist/Select.d.ts +98 -0
  76. package/dist/Select.d.ts.map +1 -0
  77. package/dist/Select.js +79 -122
  78. package/dist/Table.d.ts +48 -0
  79. package/dist/Table.d.ts.map +1 -0
  80. package/dist/Table.js +141 -121
  81. package/dist/VisuallyHidden.d.ts +8 -0
  82. package/dist/VisuallyHidden.d.ts.map +1 -0
  83. package/dist/VisuallyHidden.js +28 -0
  84. package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts +3 -0
  85. package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts.map +1 -0
  86. package/dist/{defineElement-ba770aed.js → _rollupPluginBabelHelpers-20f659f4.js} +1 -15
  87. package/dist/defineElement-40372b4b.d.ts +9 -0
  88. package/dist/defineElement-40372b4b.d.ts.map +1 -0
  89. package/dist/defineElement-40372b4b.js +15 -0
  90. package/dist/icon-03e86700.d.ts +11 -0
  91. package/dist/icon-03e86700.d.ts.map +1 -0
  92. package/dist/index.js.d.ts +21 -0
  93. package/dist/index.js.d.ts.map +1 -0
  94. package/dist/index.js.js +42 -0
  95. package/dist/leu-accordion.d.ts +3 -0
  96. package/dist/leu-accordion.d.ts.map +1 -0
  97. package/dist/leu-accordion.js +9 -0
  98. package/dist/leu-breadcrumb.d.ts +3 -0
  99. package/dist/leu-breadcrumb.d.ts.map +1 -0
  100. package/dist/leu-breadcrumb.js +23 -0
  101. package/dist/leu-button-group.d.ts +3 -0
  102. package/dist/leu-button-group.d.ts.map +1 -0
  103. package/dist/leu-button-group.js +6 -6
  104. package/dist/leu-button.d.ts +3 -0
  105. package/dist/leu-button.d.ts.map +1 -0
  106. package/dist/leu-button.js +7 -3
  107. package/dist/leu-checkbox-group.d.ts +3 -0
  108. package/dist/leu-checkbox-group.d.ts.map +1 -0
  109. package/dist/leu-checkbox-group.js +6 -3
  110. package/dist/leu-checkbox.d.ts +3 -0
  111. package/dist/leu-checkbox.d.ts.map +1 -0
  112. package/dist/leu-checkbox.js +6 -3
  113. package/dist/leu-chip-group.d.ts +3 -0
  114. package/dist/leu-chip-group.d.ts.map +1 -0
  115. package/dist/leu-chip-group.js +7 -3
  116. package/dist/leu-chip-link.d.ts +3 -0
  117. package/dist/leu-chip-link.d.ts.map +1 -0
  118. package/dist/leu-chip-link.js +7 -4
  119. package/dist/leu-chip-removable.d.ts +3 -0
  120. package/dist/leu-chip-removable.d.ts.map +1 -0
  121. package/dist/leu-chip-removable.js +7 -4
  122. package/dist/leu-chip-selectable.d.ts +3 -0
  123. package/dist/leu-chip-selectable.d.ts.map +1 -0
  124. package/dist/leu-chip-selectable.js +7 -4
  125. package/dist/leu-dropdown.d.ts +3 -0
  126. package/dist/leu-dropdown.d.ts.map +1 -0
  127. package/dist/leu-dropdown.js +15 -4
  128. package/dist/leu-input.d.ts +3 -0
  129. package/dist/leu-input.d.ts.map +1 -0
  130. package/dist/leu-input.js +7 -3
  131. package/dist/leu-menu-item.d.ts +3 -0
  132. package/dist/leu-menu-item.d.ts.map +1 -0
  133. package/dist/leu-menu-item.js +8 -3
  134. package/dist/leu-menu.d.ts +3 -0
  135. package/dist/leu-menu.d.ts.map +1 -0
  136. package/dist/leu-menu.js +6 -3
  137. package/dist/leu-pagination.d.ts +3 -0
  138. package/dist/leu-pagination.d.ts.map +1 -0
  139. package/dist/leu-pagination.js +12 -4
  140. package/dist/leu-popup.d.ts +3 -0
  141. package/dist/leu-popup.d.ts.map +1 -0
  142. package/dist/leu-popup.js +9 -0
  143. package/dist/leu-radio-group.d.ts +3 -0
  144. package/dist/leu-radio-group.d.ts.map +1 -0
  145. package/dist/leu-radio-group.js +6 -3
  146. package/dist/leu-radio.d.ts +3 -0
  147. package/dist/leu-radio.d.ts.map +1 -0
  148. package/dist/leu-radio.js +6 -3
  149. package/dist/leu-scroll-top.d.ts +3 -0
  150. package/dist/leu-scroll-top.d.ts.map +1 -0
  151. package/dist/leu-scroll-top.js +14 -0
  152. package/dist/leu-select.d.ts +3 -0
  153. package/dist/leu-select.d.ts.map +1 -0
  154. package/dist/leu-select.js +16 -4
  155. package/dist/leu-table.d.ts +3 -0
  156. package/dist/leu-table.d.ts.map +1 -0
  157. package/dist/leu-table.js +13 -4
  158. package/dist/leu-visually-hidden.d.ts +3 -0
  159. package/dist/leu-visually-hidden.d.ts.map +1 -0
  160. package/dist/leu-visually-hidden.js +8 -0
  161. package/dist/theme.css +386 -2
  162. package/dist/utils-65469421.d.ts +16 -0
  163. package/dist/utils-65469421.d.ts.map +1 -0
  164. package/dist/utils-65469421.js +35 -0
  165. package/index.js +3 -0
  166. package/package.json +47 -17
  167. package/postcss.config.cjs +2 -0
  168. package/rollup.config.js +21 -40
  169. package/scripts/generate-component/templates/[Name].js +0 -5
  170. package/scripts/generate-component/templates/[name].css +3 -3
  171. package/scripts/generate-component/templates/[namespace]-[name].js +5 -2
  172. package/scripts/postcss-leu-font-styles.cjs +160 -0
  173. package/src/components/accordion/Accordion.js +0 -6
  174. package/src/components/accordion/accordion.css +2 -2
  175. package/src/components/accordion/leu-accordion.js +5 -2
  176. package/src/components/accordion/stories/accordion.stories.js +8 -4
  177. package/src/components/accordion/test/accordion.test.js +95 -3
  178. package/src/components/breadcrumb/Breadcrumb.js +311 -0
  179. package/src/components/breadcrumb/breadcrumb.css +103 -0
  180. package/src/components/breadcrumb/leu-breadcrumb.js +6 -0
  181. package/src/components/breadcrumb/stories/breadcrumb.stories.js +73 -0
  182. package/src/components/breadcrumb/test/breadcrumb.test.js +141 -0
  183. package/src/components/button/Button.js +76 -20
  184. package/src/components/button/button.css +13 -5
  185. package/src/components/button/leu-button.js +5 -2
  186. package/src/components/button/stories/button.stories.js +79 -105
  187. package/src/components/button/test/button.test.js +184 -3
  188. package/src/components/button-group/ButtonGroup.js +76 -40
  189. package/src/components/button-group/leu-button-group.js +5 -2
  190. package/src/components/button-group/stories/button-group.stories.js +19 -6
  191. package/src/components/button-group/test/button-group.test.js +87 -4
  192. package/src/components/checkbox/Checkbox.js +6 -85
  193. package/src/components/checkbox/CheckboxGroup.js +8 -38
  194. package/src/components/checkbox/checkbox-group.css +29 -0
  195. package/src/components/checkbox/checkbox.css +76 -0
  196. package/src/components/checkbox/leu-checkbox-group.js +5 -2
  197. package/src/components/checkbox/leu-checkbox.js +5 -2
  198. package/src/components/checkbox/stories/checkbox-group.stories.js +44 -21
  199. package/src/components/checkbox/stories/checkbox.stories.js +7 -1
  200. package/src/components/checkbox/test/checkbox-group.test.js +124 -0
  201. package/src/components/checkbox/test/checkbox.test.js +72 -59
  202. package/src/components/chip/Chip.js +1 -0
  203. package/src/components/chip/ChipGroup.js +42 -7
  204. package/src/components/chip/ChipLink.js +1 -6
  205. package/src/components/chip/ChipRemovable.js +2 -7
  206. package/src/components/chip/ChipSelectable.js +5 -10
  207. package/src/components/chip/chip-group.css +12 -2
  208. package/src/components/chip/chip.css +14 -3
  209. package/src/components/chip/exports.js +4 -10
  210. package/src/components/chip/leu-chip-group.js +5 -2
  211. package/src/components/chip/leu-chip-link.js +5 -2
  212. package/src/components/chip/leu-chip-removable.js +5 -2
  213. package/src/components/chip/leu-chip-selectable.js +5 -2
  214. package/src/components/chip/stories/chip-group.stories.js +110 -44
  215. package/src/components/chip/stories/chip-link.stories.js +16 -4
  216. package/src/components/chip/stories/chip-removable.stories.js +15 -4
  217. package/src/components/chip/stories/chip-selectable.stories.js +13 -3
  218. package/src/components/chip/test/chip-group.test.js +124 -0
  219. package/src/components/chip/test/chip-link.test.js +58 -0
  220. package/src/components/chip/test/chip-removable.test.js +79 -0
  221. package/src/components/chip/test/chip-selectable.test.js +95 -0
  222. package/src/components/chip/test/chip.test.js +1 -1
  223. package/src/components/dropdown/Dropdown.js +72 -24
  224. package/src/components/dropdown/dropdown.css +1 -2
  225. package/src/components/dropdown/leu-dropdown.js +5 -2
  226. package/src/components/dropdown/stories/dropdown.stories.js +11 -5
  227. package/src/components/dropdown/test/dropdown.test.js +6 -6
  228. package/src/components/icon/icon.js +1 -1
  229. package/src/components/icon/test/icon.test.js +66 -0
  230. package/src/components/input/Input.js +25 -28
  231. package/src/components/input/input.css +11 -8
  232. package/src/components/input/leu-input.js +5 -2
  233. package/src/components/input/stories/input.stories.js +21 -2
  234. package/src/components/input/test/input.test.js +432 -4
  235. package/src/components/menu/Menu.js +0 -5
  236. package/src/components/menu/MenuItem.js +20 -13
  237. package/src/components/menu/leu-menu-item.js +5 -2
  238. package/src/components/menu/leu-menu.js +5 -2
  239. package/src/components/menu/menu-item.css +7 -4
  240. package/src/components/menu/stories/menu-item.stories.js +13 -4
  241. package/src/components/menu/stories/menu.stories.js +11 -5
  242. package/src/components/menu/test/menu-item.test.js +180 -0
  243. package/src/components/menu/test/menu.test.js +10 -2
  244. package/src/components/pagination/Pagination.js +118 -99
  245. package/src/components/pagination/leu-pagination.js +5 -2
  246. package/src/components/pagination/pagination.css +6 -1
  247. package/src/components/pagination/stories/pagination.stories.js +30 -9
  248. package/src/components/pagination/test/pagination.test.js +191 -5
  249. package/src/components/popup/Popup.js +200 -0
  250. package/src/components/popup/leu-popup.js +6 -0
  251. package/src/components/popup/popup.css +27 -0
  252. package/src/components/popup/stories/popup.stories.js +58 -0
  253. package/src/components/popup/test/popup.test.js +29 -0
  254. package/src/components/radio/Radio.js +2 -6
  255. package/src/components/radio/RadioGroup.js +6 -38
  256. package/src/components/radio/leu-radio-group.js +5 -2
  257. package/src/components/radio/leu-radio.js +5 -2
  258. package/src/components/radio/radio-group.css +29 -0
  259. package/src/components/radio/radio.css +1 -1
  260. package/src/components/radio/stories/radio-group.stories.js +38 -19
  261. package/src/components/radio/stories/radio.stories.js +7 -1
  262. package/src/components/radio/test/radio-group.test.js +86 -0
  263. package/src/components/radio/test/radio.test.js +108 -17
  264. package/src/components/scroll-top/ScrollTop.js +87 -0
  265. package/src/components/scroll-top/leu-scroll-top.js +6 -0
  266. package/src/components/scroll-top/scroll-top.css +34 -0
  267. package/src/components/scroll-top/stories/scroll-top.stories.js +217 -0
  268. package/src/components/scroll-top/test/scroll-top.test.js +22 -0
  269. package/src/components/select/Select.js +58 -37
  270. package/src/components/select/leu-select.js +5 -2
  271. package/src/components/select/select.css +15 -15
  272. package/src/components/select/stories/select.stories.js +15 -168
  273. package/src/components/select/test/fixtures.js +162 -0
  274. package/src/components/select/test/select.test.js +236 -12
  275. package/src/components/table/Table.js +43 -118
  276. package/src/components/table/leu-table.js +5 -2
  277. package/src/components/table/stories/table.stories.js +20 -10
  278. package/src/components/table/table.css +99 -0
  279. package/src/components/table/test/table.test.js +1 -1
  280. package/src/components/visually-hidden/VisuallyHidden.js +13 -0
  281. package/src/components/visually-hidden/leu-visually-hidden.js +6 -0
  282. package/src/components/visually-hidden/stories/visually-hidden.stories.js +22 -0
  283. package/src/components/visually-hidden/test/visually-hidden.test.js +36 -0
  284. package/src/components/visually-hidden/visually-hidden.css +10 -0
  285. package/src/lib/defineElement.js +1 -1
  286. package/src/lib/hasSlotController.js +5 -3
  287. package/src/lib/utils.js +35 -0
  288. package/src/styles/custom-properties.css +6 -2
  289. package/src/styles/font-definitions.json +202 -0
  290. package/stylelint.config.mjs +2 -0
  291. package/tsconfig.build.json +21 -0
  292. package/tsconfig.json +16 -0
  293. package/{web-dev-server-storybook.config.mjs → web-dev-server.config.mjs} +1 -2
  294. package/web-test-runner.config.mjs +15 -2
  295. package/dist/index.js +0 -26
@@ -1,29 +1,253 @@
1
1
  import { html } from "lit"
2
- import { fixture, expect } from "@open-wc/testing"
2
+ import { ifDefined } from "lit/directives/if-defined.js"
3
+ import { fixture, expect, elementUpdated } from "@open-wc/testing"
4
+ import { sendKeys } from "@web/test-runner-commands"
3
5
 
4
6
  import "../leu-select.js"
7
+ import { MUNICIPALITIES } from "./fixtures.js"
5
8
 
6
- async function defaultFixture() {
7
- return fixture(html`
8
- <leu-select
9
- options='[{"label":"Option 1", "value":"1"}, "Option 2", "Option 3", "Sehr lange Option um zu schauen was passiert, wenn es zu lang wird."]'
10
- label="Label"
11
- value=${null}
12
- >
13
- </leu-select>
14
- `)
9
+ async function defaultFixture(args = {}) {
10
+ return fixture(html`<leu-select
11
+ .options=${args.options}
12
+ label=${ifDefined(args.label)}
13
+ .value=${args.value ?? []}
14
+ ?clearable=${args.clearable}
15
+ ?disabled=${args.disabled}
16
+ ?filterable=${args.filterable}
17
+ ?multiple=${args.multiple}
18
+ >
19
+ </leu-select> `)
15
20
  }
16
21
 
17
22
  describe("LeuSelect", () => {
18
23
  it("is a defined element", async () => {
19
- const el = await customElements.get("leu-select")
24
+ const el = customElements.get("leu-select")
20
25
 
21
26
  await expect(el).not.to.be.undefined
22
27
  })
23
28
 
24
29
  it("passes the a11y audit", async () => {
25
- const el = await defaultFixture()
30
+ const el = await defaultFixture({
31
+ options: MUNICIPALITIES,
32
+ label: "Gemeinde",
33
+ })
26
34
 
27
35
  await expect(el).shadowDom.to.be.accessible()
28
36
  })
37
+
38
+ it("passes the a11y audit in the open state", async () => {
39
+ const el = await defaultFixture({
40
+ options: MUNICIPALITIES,
41
+ label: "Gemeinde",
42
+ open: true,
43
+ })
44
+
45
+ await expect(el).shadowDom.to.be.accessible()
46
+ })
47
+
48
+ it("renders a label", async () => {
49
+ const el = await defaultFixture({
50
+ options: MUNICIPALITIES,
51
+ label: "Gemeinde",
52
+ })
53
+
54
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
55
+
56
+ expect(toggleButton).to.have.trimmed.text("Gemeinde")
57
+ })
58
+
59
+ it("doesn't show the list of options by default", async () => {
60
+ const el = await defaultFixture({
61
+ options: MUNICIPALITIES,
62
+ label: "Gemeinde",
63
+ })
64
+
65
+ const dialog = el.shadowRoot.querySelector("dialog")
66
+
67
+ expect(dialog).to.not.have.attribute("open")
68
+ })
69
+
70
+ it("opens the list of options when the toggle button is clicked", async () => {
71
+ const el = await defaultFixture({
72
+ options: MUNICIPALITIES,
73
+ label: "Gemeinde",
74
+ })
75
+
76
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
77
+ toggleButton.click()
78
+
79
+ const dialog = el.shadowRoot.querySelector("dialog")
80
+ await elementUpdated(el)
81
+
82
+ expect(dialog).to.have.attribute("open")
83
+ })
84
+
85
+ it("has a default value of an empty array", async () => {
86
+ const el = await defaultFixture({
87
+ options: MUNICIPALITIES,
88
+ label: "Gemeinde",
89
+ })
90
+
91
+ expect(el.value).to.deep.equal([])
92
+ })
93
+
94
+ it("marks the menu item as selected a the value is set", async () => {
95
+ const el = await defaultFixture({
96
+ options: MUNICIPALITIES,
97
+ label: "Gemeinde",
98
+ value: "Affoltern am Albis",
99
+ })
100
+
101
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
102
+ toggleButton.click()
103
+
104
+ const menuItem = el.shadowRoot.querySelector(
105
+ "leu-menu-item[label='Affoltern am Albis']"
106
+ )
107
+
108
+ expect(menuItem).to.have.attribute("active")
109
+ expect(menuItem).to.have.attribute("aria-selected")
110
+ })
111
+
112
+ it("shows the clear button when a value is set", async () => {
113
+ const el = await defaultFixture({
114
+ options: MUNICIPALITIES,
115
+ label: "Gemeinde",
116
+ value: "Affoltern am Albis",
117
+ clearable: true,
118
+ })
119
+
120
+ const clearButton = el.shadowRoot.querySelector(".clear-button")
121
+
122
+ expect(clearButton).to.exist
123
+ })
124
+
125
+ it("renders a input field to filter the options", async () => {
126
+ const el = await defaultFixture({
127
+ options: MUNICIPALITIES,
128
+ label: "Gemeinde",
129
+ filterable: true,
130
+ })
131
+
132
+ const filterInput = el.shadowRoot.querySelector(".select-search")
133
+
134
+ expect(filterInput).to.exist
135
+ })
136
+
137
+ it("filters the options when the filter input is changed", async () => {
138
+ const el = await defaultFixture({
139
+ options: MUNICIPALITIES,
140
+ label: "Gemeinde",
141
+ filterable: true,
142
+ })
143
+
144
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
145
+ toggleButton.click()
146
+
147
+ const filterInput = el.shadowRoot.querySelector(".select-search")
148
+ filterInput.focus()
149
+
150
+ await sendKeys({ type: "am albis" })
151
+
152
+ const menuItems = el.shadowRoot.querySelectorAll("leu-menu-item")
153
+ expect(menuItems.length).to.equal(6)
154
+ })
155
+
156
+ it("resets the filter when the filter input is cleared", async () => {
157
+ const el = await defaultFixture({
158
+ options: MUNICIPALITIES,
159
+ label: "Gemeinde",
160
+ filterable: true,
161
+ })
162
+
163
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
164
+ toggleButton.click()
165
+
166
+ const filterInput = el.shadowRoot.querySelector(".select-search")
167
+ filterInput.focus()
168
+
169
+ await sendKeys({ type: "am albis" })
170
+
171
+ const clearFilterButton =
172
+ filterInput.shadowRoot.querySelector(".clear-button")
173
+ clearFilterButton.click()
174
+ await elementUpdated(el)
175
+
176
+ const menuItems = el.shadowRoot.querySelectorAll("leu-menu-item")
177
+ expect(menuItems.length).to.equal(MUNICIPALITIES.length)
178
+ })
179
+
180
+ it("renders a message when no options are available", async () => {
181
+ const el = await defaultFixture({
182
+ options: [],
183
+ label: "Gemeinde",
184
+ })
185
+
186
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
187
+ toggleButton.click()
188
+
189
+ const menuItem = el.shadowRoot.querySelector("leu-menu-item")
190
+ expect(menuItem).to.have.attribute("label", "Keine Optionen")
191
+ })
192
+
193
+ it("renders a message when no options are available after filtering", async () => {
194
+ const el = await defaultFixture({
195
+ options: MUNICIPALITIES,
196
+ label: "Gemeinde",
197
+ filterable: true,
198
+ })
199
+
200
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
201
+ toggleButton.click()
202
+
203
+ const filterInput = el.shadowRoot.querySelector(".select-search")
204
+ filterInput.focus()
205
+
206
+ await sendKeys({ type: "am albissss" })
207
+
208
+ const menuItem = el.shadowRoot.querySelector("leu-menu-item")
209
+ expect(menuItem).to.have.attribute("label", "Keine Resultate")
210
+ })
211
+
212
+ it("renders a apply button when multiple selection is allowed", async () => {
213
+ const el = await defaultFixture({
214
+ options: MUNICIPALITIES,
215
+ label: "Gemeinde",
216
+ multiple: true,
217
+ })
218
+
219
+ const applyButton = el.shadowRoot.querySelector("leu-menu + .apply-button")
220
+ expect(applyButton).to.exist
221
+ })
222
+
223
+ it("updates the value when an option is selected", async () => {
224
+ const el = await defaultFixture({
225
+ options: MUNICIPALITIES,
226
+ label: "Gemeinde",
227
+ })
228
+
229
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
230
+ toggleButton.click()
231
+
232
+ const menuItem = el.shadowRoot.querySelector("leu-menu-item[label='Maur']")
233
+ menuItem.click()
234
+
235
+ expect(el.value).to.deep.equal(["Maur"])
236
+ })
237
+
238
+ it("allows a value with multiple values", async () => {
239
+ const el = await defaultFixture({
240
+ options: MUNICIPALITIES,
241
+ label: "Gemeinde",
242
+ multiple: true,
243
+ })
244
+
245
+ const toggleButton = el.shadowRoot.querySelector(".select-toggle")
246
+ toggleButton.click()
247
+
248
+ el.shadowRoot.querySelector("leu-menu-item[label='Maur']").click()
249
+ el.shadowRoot.querySelector("leu-menu-item[label='Zollikon']").click()
250
+
251
+ expect(el.value).to.deep.equal(["Maur", "Zollikon"])
252
+ })
29
253
  })
@@ -1,116 +1,30 @@
1
- import { html, css, LitElement, nothing } from "lit"
1
+ import { html, LitElement, nothing } from "lit"
2
2
  import { classMap } from "lit/directives/class-map.js"
3
3
  import { styleMap } from "lit/directives/style-map.js"
4
4
  import { createRef, ref } from "lit/directives/ref.js"
5
5
  import { Icon } from "../icon/icon.js"
6
- import { defineElement } from "../../lib/defineElement.js"
7
- import { definePaginationElements } from "../pagination/Pagination.js"
6
+ import "../pagination/leu-pagination.js"
7
+
8
+ import styles from "./table.css"
8
9
 
9
10
  /**
10
11
  * @tagname leu-table
11
12
  */
12
13
  export class LeuTable extends LitElement {
13
- static styles = css`
14
- :host {
15
- position: relative;
16
- display: block;
17
- }
18
- div.scroll {
19
- display: inline-block;
20
- width: 100%;
21
- overflow: auto;
22
- }
23
- div.shadow {
24
- position: absolute;
25
- left: 0;
26
- top: 0;
27
- width: 100%;
28
- height: 100%;
29
- pointer-events: none;
30
- z-index: 1;
31
- }
32
- div.pagination {
33
- height: calc(100% - 66px);
34
- }
35
- table {
36
- width: 100%;
37
- border-spacing: 0;
38
- color: rgb(0 0 0 / 60%);
39
- font-size: 16px;
40
- font-family: var(--leu-font-regular);
41
- line-height: 1.5;
42
- }
43
- td {
44
- padding: 12px;
45
- }
46
- th {
47
- padding: 16px 16px 8px;
48
- text-align: left;
49
- font-size: 12px;
50
- font-weight: normal;
51
- font-family: var(--leu-font-black);
52
- background: var(--table-even-row-bg);
53
- }
54
- td:first-child,
55
- th:first-child {
56
- left: 0;
57
- background: inherit;
58
- z-index: 1;
59
- }
60
- tr {
61
- background: #fff;
62
- }
63
- tbody tr:nth-child(odd) {
64
- background: var(--leu-color-black-5);
65
- }
66
- button {
67
- background: none;
68
- cursor: pointer;
69
- line-height: 1.5;
70
- padding: 0;
71
- border: 0;
72
- width: 100%;
73
- display: flex;
74
- align-items: flex-center;
75
- font-size: inherit;
76
- font-family: inherit;
77
- }
78
- thead svg {
79
- display: inline-block;
80
- color: var(--leu-color-accent-blue);
81
- padding: 0;
82
- }
83
-
84
- table.sticky td:first-child,
85
- table.sticky th:first-child {
86
- position: sticky;
87
- }
88
- div.shadow-left table.sticky td:first-child,
89
- div.shadow-left table.sticky th:first-child {
90
- box-shadow: 0 0 5px rgb(0 0 0 / 50%);
91
- clip-path: inset(0 -15px 0 0);
92
- }
93
- div.shadow-left {
94
- box-shadow: inset 5px 0 5px -5px rgb(0 0 0 / 50%);
95
- }
96
- div.shadow-right {
97
- box-shadow: inset -5px 0 5px -5px rgb(0 0 0 / 50%);
98
- }
99
- `
14
+ static styles = styles
100
15
 
101
16
  static properties = {
102
17
  columns: { type: Array },
103
18
  data: { type: Array },
104
19
  firstColumnSticky: { type: Boolean, reflect: true },
105
- itemsOnAPage: { type: Number, reflect: true },
20
+ itemsPerPage: { type: Number, reflect: true },
106
21
  sortIndex: { type: Number, reflect: true },
107
22
  sortOrderAsc: { type: Boolean, reflect: true },
108
23
  width: { type: Number, reflect: true },
109
24
 
110
- _shadowLeft: { type: Boolean, state: true },
111
- _shadowRight: { type: Boolean, state: true },
112
- _min: { type: Number, state: true },
113
- _max: { type: Number, state: true },
25
+ _shadowLeft: { state: true },
26
+ _shadowRight: { state: true },
27
+ _page: { state: true },
114
28
  }
115
29
 
116
30
  constructor() {
@@ -122,7 +36,7 @@ export class LeuTable extends LitElement {
122
36
  /** @type {boolean} */
123
37
  this.firstColumnSticky = false
124
38
  /** @type {number} */
125
- this.itemsOnAPage = null
39
+ this.itemsPerPage = null
126
40
  /** @type {number} */
127
41
  this.sortIndex = null
128
42
  /** @type {boolean} */
@@ -140,14 +54,31 @@ export class LeuTable extends LitElement {
140
54
  this._shadowRight = false
141
55
  /** @internal */
142
56
  this._scrollRef = createRef()
57
+
143
58
  /** @internal */
144
- this._min = 0
145
- /** @internal */
146
- this._max = null
59
+ this._page = 1
60
+
61
+ this._resizeObserver = new ResizeObserver(() => {
62
+ this.shadowToggle(this._scrollRef.value)
63
+ })
64
+ }
65
+
66
+ disconnectedCallback() {
67
+ this._resizeObserver.disconnect()
68
+ }
69
+
70
+ attributeChangedCallback(name, oldVal, newVal) {
71
+ super.attributeChangedCallback(name, oldVal, newVal)
72
+
73
+ if (name === "itemsperpage" || name === "data") {
74
+ this._page = 1
75
+ }
147
76
  }
148
77
 
149
78
  firstUpdated() {
150
79
  this.shadowToggle(this._scrollRef.value)
80
+
81
+ this._resizeObserver.observe(this._scrollRef.value)
151
82
  }
152
83
 
153
84
  shadowToggle(target) {
@@ -205,8 +136,11 @@ export class LeuTable extends LitElement {
205
136
  }
206
137
 
207
138
  get _data() {
208
- return this.itemsOnAPage && this.itemsOnAPage > 0
209
- ? this._sortedData.slice(this._min, this._max)
139
+ return this.itemsPerPage && this.itemsPerPage > 0
140
+ ? this._sortedData.slice(
141
+ (this._page - 1) * this.itemsPerPage,
142
+ this._page * this.itemsPerPage
143
+ )
210
144
  : this._sortedData
211
145
  }
212
146
 
@@ -219,13 +153,13 @@ export class LeuTable extends LitElement {
219
153
  const shadowClassesLeft = {
220
154
  shadow: true,
221
155
  "shadow-left": !this.firstColumnSticky && this._shadowLeft,
222
- pagination: this.itemsOnAPage > 0,
156
+ pagination: this.itemsPerPage > 0,
223
157
  }
224
158
 
225
159
  const shadowClassesRight = {
226
160
  shadow: true,
227
161
  "shadow-right": this._shadowRight,
228
- pagination: this.itemsOnAPage > 0,
162
+ pagination: this.itemsPerPage > 0,
229
163
  }
230
164
 
231
165
  const stickyClass = {
@@ -274,18 +208,14 @@ export class LeuTable extends LitElement {
274
208
  <div class=${classMap(shadowClassesRight)}></div>
275
209
  </div>
276
210
 
277
- ${this.itemsOnAPage > 0
211
+ ${this.itemsPerPage > 0
278
212
  ? html`
279
213
  <leu-pagination
280
- .dataLength=${this._sortedData.length}
281
- .itemsOnAPage=${this.itemsOnAPage}
282
- @range-updated=${(e) => {
283
- this._min = e.detail.min
284
- this._max = e.detail.max
285
- // after render
286
- setTimeout(() => {
287
- this.shadowToggle(this._scrollRef.value)
288
- }, 0)
214
+ .numOfItems=${this._sortedData.length}
215
+ .itemsPerPage=${this.itemsPerPage}
216
+ page=${this._page}
217
+ @leu:pagechange=${(e) => {
218
+ this._page = e.detail.page
289
219
  }}
290
220
  >
291
221
  </leu-pagination>
@@ -294,8 +224,3 @@ export class LeuTable extends LitElement {
294
224
  `
295
225
  }
296
226
  }
297
-
298
- export function defineTableElements() {
299
- definePaginationElements()
300
- defineElement("table", LeuTable)
301
- }
@@ -1,3 +1,6 @@
1
- import { defineTableElements } from "./Table.js"
1
+ import { defineElement } from "../../lib/defineElement.js"
2
+ import { LeuTable } from "./Table.js"
2
3
 
3
- defineTableElements()
4
+ export { LeuTable }
5
+
6
+ defineElement("table", LeuTable)
@@ -4,15 +4,17 @@ import "../leu-table.js"
4
4
  export default {
5
5
  title: "Table",
6
6
  component: "leu-table",
7
+ parameters: {
8
+ design: {
9
+ type: "figma",
10
+ url: "https://www.figma.com/file/d6Pv21UVUbnBs3AdcZijHmbN/KTZH-Design-System?type=design&node-id=316-2445&mode=design&t=lzVrtq8lxYVJU5TB-11",
11
+ },
12
+ },
7
13
  }
8
14
 
9
- function Template({ itemsOnAPage }) {
15
+ function Template({ itemsPerPage }) {
10
16
  return html`
11
- <leu-table
12
- id="table"
13
- itemsOnAPage=${itemsOnAPage}
14
- style="max-width:500px;"
15
- ></leu-table>
17
+ <leu-table id="table" itemsPerPage=${itemsPerPage}></leu-table>
16
18
  <script>
17
19
  {
18
20
  const table = document.querySelector("leu-table[id=table]")
@@ -39,7 +41,10 @@ function Template({ itemsOnAPage }) {
39
41
  value: (row) => row.menge,
40
42
  style: (row) => {
41
43
  return {
42
- color: row.menge > 10 ? "green" : "red",
44
+ color:
45
+ row.menge > 10
46
+ ? "var(--leu-color-func-green)"
47
+ : "var(--leu-color-func-red)",
43
48
  }
44
49
  },
45
50
  sort: {
@@ -96,7 +101,7 @@ function Template({ itemsOnAPage }) {
96
101
 
97
102
  export const Regular = Template.bind({})
98
103
  Regular.argTypes = {
99
- itemsOnAPage: { type: "number" },
104
+ itemsPerPage: { type: "number" },
100
105
  columns: { table: { disable: true } },
101
106
  data: { table: { disable: true } },
102
107
  _columns: { table: { disable: true } },
@@ -108,9 +113,14 @@ Regular.argTypes = {
108
113
  _sortArrowDown: { table: { disable: true } },
109
114
  _sortArrowUp: { table: { disable: true } },
110
115
  _scrollRef: { table: { disable: true } },
111
- _itemsOnAPage: { table: { disable: true } },
116
+ _itemsPerPage: { table: { disable: true } },
112
117
  _sortedData: { table: { disable: true } },
113
118
  }
114
119
  Regular.args = {
115
- itemsOnAPage: null,
120
+ itemsPerPage: null,
121
+ }
122
+
123
+ export const Pagination = Template.bind({})
124
+ Pagination.args = {
125
+ itemsPerPage: 10,
116
126
  }
@@ -0,0 +1,99 @@
1
+ :host {
2
+ position: relative;
3
+ display: block;
4
+ }
5
+
6
+ div.scroll {
7
+ display: inline-block;
8
+ width: 100%;
9
+ overflow: auto;
10
+ }
11
+
12
+ div.shadow {
13
+ position: absolute;
14
+ left: 0;
15
+ top: 0;
16
+ width: 100%;
17
+ height: 100%;
18
+ pointer-events: none;
19
+ z-index: 1;
20
+ }
21
+
22
+ div.pagination {
23
+ height: calc(100% - 66px);
24
+ }
25
+
26
+ table {
27
+ width: 100%;
28
+ border-spacing: 0;
29
+ color: rgb(0 0 0 / 60%);
30
+ font-size: 16px;
31
+ font-family: var(--leu-font-family-regular);
32
+ line-height: 1.5;
33
+ }
34
+
35
+ td {
36
+ padding: 12px;
37
+ }
38
+
39
+ th {
40
+ padding: 16px 16px 8px;
41
+ text-align: left;
42
+ font-size: 12px;
43
+ font-weight: normal;
44
+ font-family: var(--leu-font-family-black);
45
+ background: var(--table-even-row-bg);
46
+ }
47
+
48
+ td:first-child,
49
+ th:first-child {
50
+ left: 0;
51
+ background: inherit;
52
+ z-index: 1;
53
+ }
54
+
55
+ tr {
56
+ background: #fff;
57
+ }
58
+
59
+ tbody tr:nth-child(odd) {
60
+ background: var(--leu-color-black-5);
61
+ }
62
+
63
+ button {
64
+ background: none;
65
+ cursor: pointer;
66
+ line-height: 1.5;
67
+ padding: 0;
68
+ border: 0;
69
+ width: 100%;
70
+ display: flex;
71
+ align-items: flex-center;
72
+ font-size: inherit;
73
+ font-family: inherit;
74
+ }
75
+
76
+ thead svg {
77
+ display: inline-block;
78
+ color: var(--leu-color-accent-blue);
79
+ padding: 0;
80
+ }
81
+
82
+ table.sticky td:first-child,
83
+ table.sticky th:first-child {
84
+ position: sticky;
85
+ }
86
+
87
+ div.shadow-left table.sticky td:first-child,
88
+ div.shadow-left table.sticky th:first-child {
89
+ box-shadow: 0 0 5px rgb(0 0 0 / 50%);
90
+ clip-path: inset(0 -15px 0 0);
91
+ }
92
+
93
+ div.shadow-left {
94
+ box-shadow: inset 5px 0 5px -5px rgb(0 0 0 / 50%);
95
+ }
96
+
97
+ div.shadow-right {
98
+ box-shadow: inset -5px 0 5px -5px rgb(0 0 0 / 50%);
99
+ }
@@ -23,7 +23,7 @@ async function defaultFixture() {
23
23
 
24
24
  describe("LeuTable", () => {
25
25
  it("is a defined element", async () => {
26
- const el = await customElements.get("leu-table")
26
+ const el = customElements.get("leu-table")
27
27
 
28
28
  await expect(el).not.to.be.undefined
29
29
  })
@@ -0,0 +1,13 @@
1
+ import { html, LitElement } from "lit"
2
+ import styles from "./visually-hidden.css"
3
+
4
+ /**
5
+ * @tagname leu-visually-hidden
6
+ */
7
+ export class LeuVisuallyHidden extends LitElement {
8
+ static styles = styles
9
+
10
+ render() {
11
+ return html`<slot></slot>`
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ import { defineElement } from "../../lib/defineElement.js"
2
+ import { LeuVisuallyHidden } from "./VisuallyHidden.js"
3
+
4
+ export { LeuVisuallyHidden }
5
+
6
+ defineElement("visually-hidden", LeuVisuallyHidden)