@graupl/graupl 1.0.0-beta.1 → 1.0.0-beta.11

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 (382) hide show
  1. package/dist/css/base/button.css +1 -1
  2. package/dist/css/base/button.css.map +1 -1
  3. package/dist/css/base/form.css +1 -1
  4. package/dist/css/base/form.css.map +1 -1
  5. package/dist/css/base/link.css +1 -1
  6. package/dist/css/base/link.css.map +1 -1
  7. package/dist/css/base/table.css +1 -1
  8. package/dist/css/base/table.css.map +1 -1
  9. package/dist/css/base.css +1 -1
  10. package/dist/css/base.css.map +1 -1
  11. package/dist/css/component/accordion.css +4 -1
  12. package/dist/css/component/accordion.css.map +1 -1
  13. package/dist/css/component/alert.css +1 -1
  14. package/dist/css/component/alert.css.map +1 -1
  15. package/dist/css/component/card.css +1 -1
  16. package/dist/css/component/card.css.map +1 -1
  17. package/dist/css/component/carousel.css +1 -1
  18. package/dist/css/component/carousel.css.map +1 -1
  19. package/dist/css/component/input-group.css +1 -1
  20. package/dist/css/component/input-group.css.map +1 -1
  21. package/dist/css/component/list.css +2 -0
  22. package/dist/css/component/list.css.map +1 -0
  23. package/dist/css/component/menu.css +1 -1
  24. package/dist/css/component/menu.css.map +1 -1
  25. package/dist/css/component/navigation.css +1 -1
  26. package/dist/css/component/navigation.css.map +1 -1
  27. package/dist/css/component.css +4 -1
  28. package/dist/css/component.css.map +1 -1
  29. package/dist/css/graupl.css +4 -1
  30. package/dist/css/graupl.css.map +1 -1
  31. package/dist/css/init.css.map +1 -1
  32. package/dist/css/layout/columns.css +1 -1
  33. package/dist/css/layout/columns.css.map +1 -1
  34. package/dist/css/layout/container.css +1 -1
  35. package/dist/css/layout/container.css.map +1 -1
  36. package/dist/css/layout/flex-columns.css +1 -1
  37. package/dist/css/layout/flex-columns.css.map +1 -1
  38. package/dist/css/layout.css +4 -1
  39. package/dist/css/layout.css.map +1 -1
  40. package/dist/css/normalize.css +1 -1
  41. package/dist/css/normalize.css.map +1 -1
  42. package/dist/css/state/focus.css +1 -1
  43. package/dist/css/state/focus.css.map +1 -1
  44. package/dist/css/state.css +1 -1
  45. package/dist/css/state.css.map +1 -1
  46. package/dist/css/theme/color.css +1 -1
  47. package/dist/css/theme/color.css.map +1 -1
  48. package/dist/css/theme/typography.css +1 -1
  49. package/dist/css/theme/typography.css.map +1 -1
  50. package/dist/css/theme.css +1 -1
  51. package/dist/css/theme.css.map +1 -1
  52. package/dist/css/utilities/alignment.css +1 -1
  53. package/dist/css/utilities/alignment.css.map +1 -1
  54. package/dist/css/utilities/background.css +2 -0
  55. package/dist/css/utilities/background.css.map +1 -0
  56. package/dist/css/utilities/border.css +2 -0
  57. package/dist/css/utilities/border.css.map +1 -0
  58. package/dist/css/utilities/color.css +1 -1
  59. package/dist/css/utilities/color.css.map +1 -1
  60. package/dist/css/utilities/container.css +2 -0
  61. package/dist/css/utilities/container.css.map +1 -0
  62. package/dist/css/utilities/display.css +1 -1
  63. package/dist/css/utilities/display.css.map +1 -1
  64. package/dist/css/utilities/flex.css +1 -1
  65. package/dist/css/utilities/flex.css.map +1 -1
  66. package/dist/css/utilities/gradient.css +2 -0
  67. package/dist/css/utilities/gradient.css.map +1 -0
  68. package/dist/css/utilities/height.css +1 -1
  69. package/dist/css/utilities/height.css.map +1 -1
  70. package/dist/css/utilities/inset.css +1 -1
  71. package/dist/css/utilities/inset.css.map +1 -1
  72. package/dist/css/utilities/justification.css +1 -1
  73. package/dist/css/utilities/justification.css.map +1 -1
  74. package/dist/css/utilities/list.css +1 -1
  75. package/dist/css/utilities/list.css.map +1 -1
  76. package/dist/css/utilities/order.css +1 -1
  77. package/dist/css/utilities/order.css.map +1 -1
  78. package/dist/css/utilities/position.css +2 -0
  79. package/dist/css/utilities/position.css.map +1 -0
  80. package/dist/css/utilities/ratio.css +1 -1
  81. package/dist/css/utilities/ratio.css.map +1 -1
  82. package/dist/css/utilities/spacing.css +1 -1
  83. package/dist/css/utilities/spacing.css.map +1 -1
  84. package/dist/css/utilities/typography.css +1 -1
  85. package/dist/css/utilities/typography.css.map +1 -1
  86. package/dist/css/utilities/visibility.css +1 -1
  87. package/dist/css/utilities/visibility.css.map +1 -1
  88. package/dist/css/utilities/visually-hidden.css +2 -0
  89. package/dist/css/utilities/visually-hidden.css.map +1 -0
  90. package/dist/css/utilities/width.css +1 -1
  91. package/dist/css/utilities/width.css.map +1 -1
  92. package/dist/css/utilities/z-index.css +2 -0
  93. package/dist/css/utilities/z-index.css.map +1 -0
  94. package/dist/css/utilities.css +1 -1
  95. package/dist/css/utilities.css.map +1 -1
  96. package/dist/js/accordion.js +5 -0
  97. package/dist/js/accordion.js.map +1 -0
  98. package/dist/js/alert.js +5 -0
  99. package/dist/js/alert.js.map +1 -0
  100. package/dist/js/carousel.js +5 -0
  101. package/dist/js/carousel.js.map +1 -0
  102. package/dist/js/component/accordion.cjs.js +4 -2
  103. package/dist/js/component/accordion.cjs.js.map +1 -0
  104. package/dist/js/component/accordion.es.js +5 -0
  105. package/dist/js/component/accordion.es.js.map +1 -0
  106. package/dist/js/component/accordion.iife.js +4 -2
  107. package/dist/js/component/accordion.iife.js.map +1 -0
  108. package/dist/js/component/alert.cjs.js +4 -2
  109. package/dist/js/component/alert.cjs.js.map +1 -0
  110. package/dist/js/component/alert.es.js +5 -0
  111. package/dist/js/component/alert.es.js.map +1 -0
  112. package/dist/js/component/alert.iife.js +4 -2
  113. package/dist/js/component/alert.iife.js.map +1 -0
  114. package/dist/js/component/carousel.cjs.js +4 -2
  115. package/dist/js/component/carousel.cjs.js.map +1 -0
  116. package/dist/js/component/carousel.es.js +5 -0
  117. package/dist/js/component/carousel.es.js.map +1 -0
  118. package/dist/js/component/carousel.iife.js +4 -2
  119. package/dist/js/component/carousel.iife.js.map +1 -0
  120. package/dist/js/generator/accordion.cjs.js +5 -0
  121. package/dist/js/generator/accordion.cjs.js.map +1 -0
  122. package/dist/js/generator/accordion.es.js +5 -0
  123. package/dist/js/generator/accordion.es.js.map +1 -0
  124. package/dist/js/generator/accordion.iife.js +5 -0
  125. package/dist/js/generator/accordion.iife.js.map +1 -0
  126. package/dist/js/generator/carousel.cjs.js +5 -0
  127. package/dist/js/generator/carousel.cjs.js.map +1 -0
  128. package/dist/js/generator/carousel.es.js +5 -0
  129. package/dist/js/generator/carousel.es.js.map +1 -0
  130. package/dist/js/generator/carousel.iife.js +5 -0
  131. package/dist/js/generator/carousel.iife.js.map +1 -0
  132. package/dist/js/generator/navigation.cjs.js +3 -0
  133. package/dist/js/generator/navigation.cjs.js.map +1 -0
  134. package/dist/js/generator/navigation.es.js +3 -0
  135. package/dist/js/generator/navigation.es.js.map +1 -0
  136. package/dist/js/generator/navigation.iife.js +3 -0
  137. package/dist/js/generator/navigation.iife.js.map +1 -0
  138. package/dist/js/graupl.js +9 -0
  139. package/dist/js/graupl.js.map +1 -0
  140. package/dist/js/navigation.js +3 -0
  141. package/dist/js/navigation.js.map +1 -0
  142. package/package.json +43 -37
  143. package/scss/base/button.scss +1 -1
  144. package/scss/base/form.scss +1 -1
  145. package/scss/base/link.scss +1 -1
  146. package/scss/base/table.scss +1 -1
  147. package/scss/base.scss +1 -1
  148. package/scss/component/accordion.scss +1 -1
  149. package/scss/component/alert.scss +1 -1
  150. package/scss/component/card.scss +1 -1
  151. package/scss/component/carousel.scss +1 -1
  152. package/scss/component/input-group.scss +1 -1
  153. package/scss/component/list.scss +3 -0
  154. package/scss/component/menu.scss +1 -1
  155. package/scss/component/navigation.scss +1 -1
  156. package/scss/component.scss +1 -1
  157. package/scss/graupl.scss +1 -1
  158. package/scss/init.scss +1 -1
  159. package/scss/layout/columns.scss +1 -1
  160. package/scss/layout/container.scss +1 -1
  161. package/scss/layout/flex-columns.scss +1 -1
  162. package/scss/layout.scss +1 -1
  163. package/scss/normalize.scss +1 -1
  164. package/scss/state/focus.scss +1 -1
  165. package/scss/state.scss +1 -1
  166. package/scss/theme/color.scss +1 -1
  167. package/scss/theme/typography.scss +1 -1
  168. package/scss/theme.scss +1 -1
  169. package/scss/utilities/alignment.scss +1 -1
  170. package/scss/utilities/background.scss +3 -0
  171. package/scss/utilities/border.scss +3 -0
  172. package/scss/utilities/color.scss +1 -1
  173. package/scss/utilities/container.scss +3 -0
  174. package/scss/utilities/display.scss +1 -1
  175. package/scss/utilities/flex.scss +1 -1
  176. package/scss/utilities/gradient.scss +3 -0
  177. package/scss/utilities/height.scss +1 -1
  178. package/scss/utilities/inset.scss +1 -1
  179. package/scss/utilities/justification.scss +1 -1
  180. package/scss/utilities/list.scss +1 -1
  181. package/scss/utilities/order.scss +1 -1
  182. package/scss/utilities/position.scss +3 -0
  183. package/scss/utilities/ratio.scss +1 -1
  184. package/scss/utilities/spacing.scss +1 -1
  185. package/scss/utilities/typography.scss +1 -1
  186. package/scss/utilities/visibility.scss +1 -1
  187. package/scss/utilities/visually-hidden.scss +3 -0
  188. package/scss/utilities/width.scss +1 -1
  189. package/scss/utilities/z-index.scss +3 -0
  190. package/scss/utilities.scss +1 -1
  191. package/.browserslistrc +0 -3
  192. package/.czrc +0 -3
  193. package/.editorconfig +0 -13
  194. package/.github/CODE_OF_CONDUCT.md +0 -73
  195. package/.github/COMMIT_CONVENTION.md +0 -17
  196. package/.github/CONTRIBUTING.md +0 -86
  197. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
  198. package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
  199. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  200. package/.github/SECURITY.md +0 -26
  201. package/.github/dependabot.yml +0 -17
  202. package/.github/pull_request_template.md +0 -5
  203. package/.github/workflows/codeql-analysis.yml +0 -71
  204. package/.github/workflows/docs.yml +0 -59
  205. package/.github/workflows/test.yml +0 -27
  206. package/.husky/commit-msg +0 -3
  207. package/.husky/pre-commit +0 -4
  208. package/.prettierignore +0 -12
  209. package/.stylelintignore +0 -9
  210. package/.versionrc.cjs +0 -61
  211. package/CHANGELOG.md +0 -364
  212. package/build.js +0 -7
  213. package/commitlint.config.js +0 -5
  214. package/dist/css/utilities/postion.css +0 -2
  215. package/dist/css/utilities/postion.css.map +0 -1
  216. package/dist/js/component/accordion.esm.js +0 -1289
  217. package/dist/js/component/alert.esm.js +0 -529
  218. package/dist/js/component/carousel.esm.js +0 -1110
  219. package/dist/js/graupl.cjs.js +0 -5
  220. package/dist/js/graupl.esm.js +0 -1462
  221. package/dist/js/graupl.iife.js +0 -5
  222. package/docs/.vitepress/config.js +0 -78
  223. package/docs/.vitepress/theme/custom.scss +0 -35
  224. package/docs/.vitepress/theme/index.js +0 -4
  225. package/docs/compiling-graupl.md +0 -56
  226. package/docs/components/alert.md +0 -130
  227. package/docs/components/button.md +0 -84
  228. package/docs/components/card.md +0 -369
  229. package/docs/components/index.md +0 -1
  230. package/docs/components/inputgroup.md +0 -159
  231. package/docs/components/menu.md +0 -326
  232. package/docs/components/navigation.md +0 -158
  233. package/docs/content.md +0 -237
  234. package/docs/defaults.md +0 -121
  235. package/docs/forms.md +0 -79
  236. package/docs/functions.md +0 -9
  237. package/docs/getting-started.md +0 -1
  238. package/docs/index.md +0 -1
  239. package/docs/introduction.md +0 -25
  240. package/docs/layout.md +0 -200
  241. package/docs/mixins.md +0 -47
  242. package/docs/state.md +0 -67
  243. package/docs/theme.md +0 -258
  244. package/docs/utilities.md +0 -357
  245. package/eslint.config.js +0 -74
  246. package/index.html +0 -851
  247. package/index.js +0 -12
  248. package/lint-staged.config.js +0 -6
  249. package/postcss.config.cjs +0 -12
  250. package/prettier.config.js +0 -16
  251. package/scss/utilities/postion.scss +0 -3
  252. package/src/js/accordion/Accordion.js +0 -1163
  253. package/src/js/accordion/AccordionItem.js +0 -496
  254. package/src/js/accordion/index.js +0 -10
  255. package/src/js/alert/Alert.js +0 -581
  256. package/src/js/alert/index.js +0 -11
  257. package/src/js/carousel/Carousel.js +0 -1427
  258. package/src/js/carousel/index.js +0 -10
  259. package/src/js/domHelpers.js +0 -37
  260. package/src/js/eventHandlers.js +0 -39
  261. package/src/js/navigation/index.js +0 -36
  262. package/src/js/storage.js +0 -106
  263. package/src/js/validate.js +0 -225
  264. package/src/scss/_defaults.scss +0 -136
  265. package/src/scss/_index.scss +0 -15
  266. package/src/scss/_init.scss +0 -3
  267. package/src/scss/_normalize.scss +0 -197
  268. package/src/scss/_variables.scss +0 -53
  269. package/src/scss/base/_index.scss +0 -6
  270. package/src/scss/base/button/_defaults.scss +0 -60
  271. package/src/scss/base/button/_index.scss +0 -107
  272. package/src/scss/base/button/_mixins.scss +0 -166
  273. package/src/scss/base/button/_variables.scss +0 -176
  274. package/src/scss/base/form/_defaults.scss +0 -17
  275. package/src/scss/base/form/_index.scss +0 -93
  276. package/src/scss/base/form/_variables.scss +0 -153
  277. package/src/scss/base/link/_defaults.scss +0 -50
  278. package/src/scss/base/link/_index.scss +0 -134
  279. package/src/scss/base/link/_variables.scss +0 -262
  280. package/src/scss/base/table/_defaults.scss +0 -53
  281. package/src/scss/base/table/_index.scss +0 -121
  282. package/src/scss/base/table/_variables.scss +0 -135
  283. package/src/scss/component/_index.scss +0 -9
  284. package/src/scss/component/accordion/_defaults.scss +0 -40
  285. package/src/scss/component/accordion/_index.scss +0 -180
  286. package/src/scss/component/accordion/_variables.scss +0 -316
  287. package/src/scss/component/alert/_defaults.scss +0 -49
  288. package/src/scss/component/alert/_index.scss +0 -118
  289. package/src/scss/component/alert/_variables.scss +0 -170
  290. package/src/scss/component/card/_defaults.scss +0 -32
  291. package/src/scss/component/card/_index.scss +0 -178
  292. package/src/scss/component/card/_variables.scss +0 -186
  293. package/src/scss/component/carousel/_defaults.scss +0 -43
  294. package/src/scss/component/carousel/_index.scss +0 -188
  295. package/src/scss/component/carousel/_variables.scss +0 -104
  296. package/src/scss/component/input-group/_defaults.scss +0 -30
  297. package/src/scss/component/input-group/_index.scss +0 -47
  298. package/src/scss/component/input-group/_variables.scss +0 -66
  299. package/src/scss/component/menu/_defaults.scss +0 -66
  300. package/src/scss/component/menu/_index.scss +0 -305
  301. package/src/scss/component/menu/_variables.scss +0 -500
  302. package/src/scss/component/navigation/_defaults.scss +0 -29
  303. package/src/scss/component/navigation/_index.scss +0 -189
  304. package/src/scss/component/navigation/_variables.scss +0 -237
  305. package/src/scss/functions/_important.scss +0 -13
  306. package/src/scss/functions/_screen.scss +0 -30
  307. package/src/scss/functions/_theme.scss +0 -39
  308. package/src/scss/layout/_index.scss +0 -5
  309. package/src/scss/layout/columns/_defaults.scss +0 -19
  310. package/src/scss/layout/columns/_index.scss +0 -58
  311. package/src/scss/layout/columns/_variables.scss +0 -51
  312. package/src/scss/layout/container/_defaults.scss +0 -17
  313. package/src/scss/layout/container/_index.scss +0 -41
  314. package/src/scss/layout/container/_variables.scss +0 -50
  315. package/src/scss/layout/flex-columns/_defaults.scss +0 -18
  316. package/src/scss/layout/flex-columns/_index.scss +0 -80
  317. package/src/scss/layout/flex-columns/_variables.scss +0 -26
  318. package/src/scss/mixins/_animation.scss +0 -15
  319. package/src/scss/mixins/_layer.scss +0 -12
  320. package/src/scss/mixins/_screen.scss +0 -56
  321. package/src/scss/mixins/_utility.scss +0 -30
  322. package/src/scss/mixins/_visually-hidden.scss +0 -20
  323. package/src/scss/state/_index.scss +0 -3
  324. package/src/scss/state/focus/_defaults.scss +0 -10
  325. package/src/scss/state/focus/_index.scss +0 -13
  326. package/src/scss/state/focus/_mixins.scss +0 -15
  327. package/src/scss/state/focus/_variables.scss +0 -44
  328. package/src/scss/theme/_index.scss +0 -4
  329. package/src/scss/theme/color/_defaults.scss +0 -143
  330. package/src/scss/theme/color/_index.scss +0 -42
  331. package/src/scss/theme/color/_variables.scss +0 -129
  332. package/src/scss/theme/typography/_defaults.scss +0 -54
  333. package/src/scss/theme/typography/_index.scss +0 -111
  334. package/src/scss/theme/typography/_variables.scss +0 -231
  335. package/src/scss/utilities/_index.scss +0 -17
  336. package/src/scss/utilities/alignment/_defaults.scss +0 -62
  337. package/src/scss/utilities/alignment/_index.scss +0 -75
  338. package/src/scss/utilities/alignment/_variables.scss +0 -6
  339. package/src/scss/utilities/color/_defaults.scss +0 -35
  340. package/src/scss/utilities/color/_index.scss +0 -91
  341. package/src/scss/utilities/color/_variables.scss +0 -6
  342. package/src/scss/utilities/display/_defaults.scss +0 -32
  343. package/src/scss/utilities/display/_index.scss +0 -61
  344. package/src/scss/utilities/display/_variables.scss +0 -6
  345. package/src/scss/utilities/flex/_defaults.scss +0 -63
  346. package/src/scss/utilities/flex/_index.scss +0 -71
  347. package/src/scss/utilities/flex/_variables.scss +0 -6
  348. package/src/scss/utilities/height/_defaults.scss +0 -41
  349. package/src/scss/utilities/height/_index.scss +0 -98
  350. package/src/scss/utilities/height/_variables.scss +0 -6
  351. package/src/scss/utilities/inset/_defaults.scss +0 -41
  352. package/src/scss/utilities/inset/_index.scss +0 -37
  353. package/src/scss/utilities/inset/_variables.scss +0 -6
  354. package/src/scss/utilities/justification/_defaults.scss +0 -59
  355. package/src/scss/utilities/justification/_index.scss +0 -75
  356. package/src/scss/utilities/justification/_variables.scss +0 -6
  357. package/src/scss/utilities/list/_defaults.scss +0 -39
  358. package/src/scss/utilities/list/_index.scss +0 -56
  359. package/src/scss/utilities/list/_variables.scss +0 -6
  360. package/src/scss/utilities/order/_defaults.scss +0 -22
  361. package/src/scss/utilities/order/_index.scss +0 -63
  362. package/src/scss/utilities/order/_variables.scss +0 -6
  363. package/src/scss/utilities/position/_defaults.scss +0 -26
  364. package/src/scss/utilities/position/_index.scss +0 -37
  365. package/src/scss/utilities/position/_variables.scss +0 -6
  366. package/src/scss/utilities/ratio/_defaults.scss +0 -28
  367. package/src/scss/utilities/ratio/_index.scss +0 -52
  368. package/src/scss/utilities/ratio/_variables.scss +0 -9
  369. package/src/scss/utilities/spacing/_defaults.scss +0 -49
  370. package/src/scss/utilities/spacing/_index.scss +0 -169
  371. package/src/scss/utilities/spacing/_variables.scss +0 -6
  372. package/src/scss/utilities/typography/_defaults.scss +0 -30
  373. package/src/scss/utilities/typography/_index.scss +0 -224
  374. package/src/scss/utilities/typography/_variables.scss +0 -6
  375. package/src/scss/utilities/visibility/_defaults.scss +0 -25
  376. package/src/scss/utilities/visibility/_index.scss +0 -36
  377. package/src/scss/utilities/visibility/_variables.scss +0 -6
  378. package/src/scss/utilities/width/_defaults.scss +0 -41
  379. package/src/scss/utilities/width/_index.scss +0 -98
  380. package/src/scss/utilities/width/_variables.scss +0 -6
  381. package/stylelint.config.js +0 -21
  382. package/vite.config.js +0 -57
@@ -1,1427 +0,0 @@
1
- /**
2
- * @file
3
- * The carousel class.
4
- */
5
-
6
- import { addClass, removeClass } from "../domHelpers.js";
7
- import { preventEvent, keyPress } from "../eventHandlers.js";
8
- import storage from "../storage.js";
9
- import {
10
- isQuerySelector,
11
- isTag,
12
- isValidClassList,
13
- isValidInstance,
14
- isValidType,
15
- } from "../validate.js";
16
-
17
- class Carousel {
18
- /**
19
- * The DOM elements within the carousel.
20
- *
21
- * @protected
22
- *
23
- * @type {Object<HTMLElement, HTMLElement[]>}
24
- *
25
- * @property {HTMLElement} carousel - The carousel element.
26
- * @property {HTMLElement[]} carouselItems - The carousel items.
27
- * @property {HTMLElement} carouselItemContainer - The carousel item container.
28
- * @property {HTMLElement[]} carouselControls - The carousel controls.
29
- * @property {HTMLElement} carouselControlContainer - The carousel control container.
30
- * @property {HTMLElement[]} carouselTabs - The carousel tabs.
31
- * @property {HTMLElement} carouselTabContainer - The carousel tab container.
32
- * @property {HTMLElement} autoplay - The autoplay button.
33
- * @property {HTMLElement} next - The next button.
34
- * @property {HTMLElement} previous - The previous button.
35
- */
36
- _dom = {
37
- carousel: null,
38
- carouselItems: [],
39
- carouselItemContainer: null,
40
- carouselControls: [],
41
- carouselControlContainer: null,
42
- carouselTabs: [],
43
- carouselTabContainer: null,
44
- autoplay: null,
45
- next: null,
46
- previous: null,
47
- };
48
-
49
- /**
50
- * The query selectors used by the carousel to populate the dom.
51
- *
52
- * @protected
53
- *
54
- * @type {Object<string>}
55
- *
56
- * @property {string} carouselItems - The query selector string for carousel items.
57
- * @property {string} carouselItemContainer - The query selector string for the carousel item container.
58
- * @property {string} carouselControls - The query selector string for carousel controls.
59
- * @property {string} carouselControlContainer - The query selector string for carousel control container.
60
- * @property {string} carouselTabs - The query selector string for the carousel tabs.
61
- * @property {string} carouselTabContainer - The query selector string for the carousel tab container.
62
- * @property {string} autoplay - The query selector string for the autoplay button.
63
- * @property {string} next - The query selector string for the next button.
64
- * @property {string} previous - The query selector string for the previous button.
65
- */
66
- _selectors = {
67
- carouselItems: "",
68
- carouselItemContainer: "",
69
- carouselControls: "",
70
- carouselControlContainer: "",
71
- carouselTabs: "",
72
- carouselTabContainer: "",
73
- autoplay: "",
74
- next: "",
75
- previous: "",
76
- };
77
-
78
- /**
79
- * The class(es) to apply when a carousel item is active.
80
- *
81
- * @protected
82
- *
83
- * @type {string|string[]}
84
- */
85
- _activeClass = "active";
86
-
87
- /**
88
- * The class(es) to apply to a carousel item that is the previously active item.
89
- *
90
- * @protected
91
- *
92
- * @type {string|string[]}
93
- */
94
- _previousClass = "previous";
95
-
96
- /**
97
- * The class(es) to apply to a carousel item that is the next active item.
98
- *
99
- * @protected
100
- *
101
- * @type {string|string[]}
102
- */
103
- _nextClass = "next";
104
-
105
- /**
106
- * The class(es) to apply to the autoplay button when the carousel is paused.
107
- *
108
- * @protected
109
- *
110
- * @type {string|string[]}
111
- */
112
- _playClass = "play";
113
-
114
- /**
115
- * The class(es) to apply to the autoplay button when the carousel is playing.
116
- *
117
- * @protected
118
- *
119
- * @type {string|string[]}
120
- */
121
- _pauseClass = "pause";
122
-
123
- /**
124
- * The index of the currently active carousel item.
125
- *
126
- * @protected
127
- *
128
- * @type {number}
129
- */
130
- _currentItem = 0;
131
-
132
- /**
133
- * A flag to indicate if the carousel is currently playing.
134
- *
135
- * @protected
136
- *
137
- * @type {boolean}
138
- */
139
- _autoplay = true;
140
-
141
- /**
142
- * A variable to delay transition slides in milliseconds.
143
- *
144
- * @protected
145
- *
146
- * @type {number}
147
- */
148
- _transitionDelay = 10000;
149
-
150
- /**
151
- * The duration time (in milliseconds) for the transition between carousel items.
152
- *
153
- * @protected
154
- *
155
- * @type {number}
156
- */
157
- _transitionDuration = 500;
158
-
159
- /**
160
- * The label for the autoplay button when the carousel is paused.
161
- *
162
- * @protected
163
- *
164
- * @type {string}
165
- */
166
- _playText = "Play";
167
-
168
- /**
169
- * The label for the autoplay button when the carousel is playing.
170
- *
171
- * @protected
172
- *
173
- * @type {string}
174
- */
175
- _pauseText = "Pause";
176
-
177
- /**
178
- * The current action being performed by the carousel.
179
- *
180
- * @protected
181
- *
182
- * @type {string}
183
- */
184
- _currentAction = "next";
185
-
186
- /**
187
- * The stored interval callback for autoplaying the carousel.
188
- *
189
- * @protected
190
- *
191
- * @type {?Function}
192
- */
193
- _autoplayInterval = null;
194
-
195
- /**
196
- * The prefix to use for CSS custom properties.
197
- *
198
- * @protected
199
- *
200
- * @type {string}
201
- */
202
- _prefix = "graupl-";
203
-
204
- /**
205
- * The key used to generate IDs throughout the carousel.
206
- *
207
- * @protected
208
- *
209
- * @type {string}
210
- */
211
- _key = "";
212
-
213
- /**
214
- * An array of error messages generated by the carousel.
215
- *
216
- * @protected
217
- *
218
- * @type {string[]}
219
- */
220
- _errors = [];
221
-
222
- /**
223
- * Contructs a new `Carousel`.
224
- *
225
- * @param {object} options - The options for the generated carousel.
226
- * @param {HTMLElement} options.carouselElement - The carousel element in the DOM.
227
- * @param {string} [options.carouselItemSelector = .carousel-item] - The query selector string for carousel items.
228
- * @param {string} [options.carouselItemContainerSelector = .carousel-item-container] - The query selector string for the carousel item container.
229
- * @param {string} [options.carouselControlSelector = .carousel-control] - The query selector string for carousel controls.
230
- * @param {string} [options.carouselControlContainerSelector = .carousel-control-container] - The query selector string for carousel control container.
231
- * @param {string} [options.carouselTabSelector = .carousel-tab] - The query selector string for carousel tabs.
232
- * @param {string} [options.carouselTabContainerSelector = .carousel-tab-container] - The query selector string for the carousel tab container.
233
- * @param {string} [options.autoplaySelector = .autoplay] - The query selector string for the autoplay button.
234
- * @param {string} [options.nextSelector = .next] - The query selector string for the next button.
235
- * @param {string} [options.previousSelector = .previous] - The query selector string for the previous button.
236
- * @param {?(string|string[])} [options.activeClass = active] - The class(es) to apply when a carousel item is active.
237
- * @param {?(string|string[])} [options.previousClass = previous] - The class(es) to apply to a carousel item that is the previously active item.
238
- * @param {?(string|string[])} [options.nextClass = next] - The class(es) to apply to a carousel item that is the next active item.
239
- * @param {?(string|string[])} [options.playClass = play] - The class(es) to apply to the autoplay button when the carousel is paused.
240
- * @param {?(string|string[])} [options.pauseClass = pause] - The class(es) to apply to the autoplay button when the carousel is playing.
241
- * @param {boolean} [options.autoplay = true] - A flag to indicate if the carousel should autoplay.
242
- * @param {number} [options.transitionDelay = 10000] - A flag to initialize the carousel immediately upon creation.
243
- * @param {number} [options.transitionDuration = 500] - The duration time (in milliseconds) for the transition between carousel items.
244
- * @param {?string} [options.playText = Play] - The text to use for the play button.
245
- * @param {?string} [options.pauseText = Pause] - The text to use for the pause button.
246
- * @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.
247
- * @param {?string} [options.key = null] - The key used to generate IDs throughout the carousel.
248
- * @param {boolean} [options.initialize = false] - A flag to initialize the carousel immediately upon creation.
249
- */
250
- constructor({
251
- carouselElement,
252
- carouselItemSelector = ".carousel-item",
253
- carouselItemContainerSelector = ".carousel-item-container",
254
- carouselControlSelector = ".carousel-control",
255
- carouselControlContainerSelector = ".carousel-control-container",
256
- carouselTabSelector = ".carousel-tab",
257
- carouselTabContainerSelector = ".carousel-tab-container",
258
- autoplaySelector = ".autoplay",
259
- nextSelector = ".next",
260
- previousSelector = ".previous",
261
- activeClass = "active",
262
- previousClass = "previous",
263
- nextClass = "next",
264
- playClass = "play",
265
- pauseClass = "pause",
266
- autoplay = true,
267
- transitionDelay = 10000,
268
- transitionDuration = 500,
269
- playText = "Play",
270
- pauseText = "Pause",
271
- prefix = "graupl-",
272
- key = null,
273
- initialize = false,
274
- }) {
275
- // Set DOM elements.
276
- this._dom.carousel = carouselElement;
277
-
278
- // Set query selectors.
279
- this._selectors.carouselItems = carouselItemSelector;
280
- this._selectors.carouselItemContainer = carouselItemContainerSelector;
281
- this._selectors.carouselControls = carouselControlSelector;
282
- this._selectors.carouselControlContainer = carouselControlContainerSelector;
283
- this._selectors.carouselTabs = carouselTabSelector;
284
- this._selectors.carouselTabContainer = carouselTabContainerSelector;
285
- this._selectors.autoplay = autoplaySelector;
286
- this._selectors.next = nextSelector;
287
- this._selectors.previous = previousSelector;
288
-
289
- // Set class names.
290
- this._activeClass = activeClass || "";
291
- this._previousClass = previousClass || "";
292
- this._nextClass = nextClass || "";
293
- this._playClass = playClass || "";
294
- this._pauseClass = pauseClass || "";
295
-
296
- // Set flags.
297
- this._autoplay = autoplay;
298
-
299
- // Set transition options.
300
- this._transitionDelay = transitionDelay;
301
- this._transitionDuration = transitionDuration;
302
-
303
- // Set labels.
304
- this._playText = playText || "";
305
- this._pauseText = pauseText || "";
306
-
307
- // Set prefix.
308
- this._prefix = prefix || "";
309
-
310
- // Set the key.
311
- this._key = key || "";
312
-
313
- if (initialize) {
314
- this.initialize();
315
- }
316
- }
317
-
318
- /**
319
- * Initializes the carousel.
320
- */
321
- initialize() {
322
- try {
323
- if (!this._validate()) {
324
- throw new Error(
325
- `Graupl Carousel: cannot initialize carousel. The following errors have been found:\n - ${this.errors.join(
326
- "\n - "
327
- )}`
328
- );
329
- }
330
-
331
- // Set up the DOM.
332
- this._generateKey();
333
- this._setDOMElements();
334
- this._setIds();
335
- this._setAriaAttributes();
336
-
337
- // Activate the first item.
338
- this.activateFirstItem();
339
-
340
- // Handle events.
341
- this._handleAutoplay();
342
- this._handleFocus();
343
- this._handleClick();
344
- this._handleHover();
345
- this._handleKeydown();
346
- this._handleKeyup();
347
-
348
- // Set the custom props.
349
- this._setTransitionDuration();
350
-
351
- // Set up the storage.
352
- storage.initializeStorage("carousels");
353
- storage.pushToStorage("carousels", this.dom.carousel.id, this);
354
- } catch (error) {
355
- console.error(error);
356
- }
357
- }
358
-
359
- /**
360
- * The HTML elements for the carousel in the DOM.
361
- *
362
- * @readonly
363
- *
364
- * @type {Object<HTMLElement>}
365
- *
366
- * @see _dom
367
- */
368
- get dom() {
369
- return this._dom;
370
- }
371
-
372
- /**
373
- * The query selectors used by the carousel to populate the dom.
374
- *
375
- * @readonly
376
- *
377
- * @type {Object<string>}
378
- *
379
- * @see _selectors
380
- */
381
- get selectors() {
382
- return this._selectors;
383
- }
384
-
385
- /**
386
- * The class(es) to apply when a carousel item is active.
387
- *
388
- * @type {string|string[]}
389
- *
390
- * @see _activeClass
391
- */
392
- get activeClass() {
393
- return this._activeClass;
394
- }
395
-
396
- /**
397
- * The class(es) to apply to a carousel item that is the next active item.
398
- *
399
- * @type {string|string[]}
400
- *
401
- * @see _previousClass
402
- */
403
- get previousClass() {
404
- return this._previousClass;
405
- }
406
-
407
- /**
408
- * The class(es) to apply to a carousel item that is the next active item.
409
- *
410
- * @type {string|string[]}
411
- *
412
- * @see _nextClass
413
- */
414
- get nextClass() {
415
- return this._nextClass;
416
- }
417
-
418
- /**
419
- * The class(es) to apply to the autoplay button when the carousel is paused.
420
- *
421
- * @type {string|string[]}
422
- *
423
- * @see _playClass
424
- */
425
- get playClass() {
426
- return this._playClass;
427
- }
428
-
429
- /**
430
- * The class(es) to apply to the autoplay button when the carousel is playing.
431
- *
432
- * @type {string|string[]}
433
- *
434
- * @see _pauseClass
435
- */
436
- get pauseClass() {
437
- return this._pauseClass;
438
- }
439
-
440
- /**
441
- * The index of the currently active carousel item.
442
- *
443
- * @type {number}
444
- *
445
- * @see _currentItem
446
- */
447
- get currentItem() {
448
- return this._currentItem;
449
- }
450
-
451
- /**
452
- * The currently active carousel item.
453
- *
454
- * @readonly
455
- *
456
- * @type {HTMLElement}
457
- */
458
- get currentCarouselItem() {
459
- return this.dom.carouselItems[this.currentItem];
460
- }
461
-
462
- /**
463
- * The currently active carousel tab.
464
- *
465
- * @readonly
466
- *
467
- * @type {HTMLElement}
468
- */
469
- get currentCarouselTab() {
470
- return this.dom.carouselTabs[this.currentItem];
471
- }
472
-
473
- /**
474
- * A flag to indicate if the carousel is currently playing.
475
- *
476
- * @type {boolean}
477
- *
478
- * @see _autoplay
479
- */
480
- get autoplay() {
481
- return this._autoplay;
482
- }
483
-
484
- /**
485
- * The delay in milliseconds before transitioning slides.
486
- *
487
- * @type {number}
488
- *
489
- * @see _transitionDelay
490
- */
491
- get transitionDelay() {
492
- return this._transitionDelay;
493
- }
494
-
495
- /**
496
- * The duration time (in milliseconds) for the transition between carousel items.
497
- *
498
- * @type {number}
499
- *
500
- * @see _transitionDuration
501
- */
502
- get transitionDuration() {
503
- return this._transitionDuration;
504
- }
505
-
506
- /**
507
- * The label for the autoplay button when the carousel is paused.
508
- *
509
- * @type {string}
510
- *
511
- * @see _playText
512
- */
513
- get playText() {
514
- return this._playText;
515
- }
516
-
517
- /**
518
- * The label for the autoplay button when the carousel is playing.
519
- *
520
- * @type {string}
521
- *
522
- * @see _pauseText
523
- */
524
- get pauseText() {
525
- return this._pauseText;
526
- }
527
-
528
- /**
529
- * The prefix to use for CSS custom properties.
530
- *
531
- * @type {string}
532
- *
533
- * @see _prefix
534
- */
535
- get prefix() {
536
- return this._prefix;
537
- }
538
-
539
- /**
540
- * The key used to generate IDs throughout the accordion.
541
- *
542
- * @type {string}
543
- *
544
- * @see _key
545
- */
546
- get key() {
547
- return this._key;
548
- }
549
-
550
- /**
551
- * The current action being performed by the carousel.
552
- *
553
- * @type {string}
554
- *
555
- * @see _currentAction
556
- */
557
- get currentAction() {
558
- return this._currentAction;
559
- }
560
-
561
- /**
562
- * An array of error messages generated by the carousel.
563
- *
564
- * @readonly
565
- *
566
- * @type {string[]}
567
- *
568
- * @see _errors
569
- */
570
- get errors() {
571
- return this._errors;
572
- }
573
-
574
- set currentItem(value) {
575
- isValidType("number", { value });
576
-
577
- if (value === this.currentItem) {
578
- return;
579
- }
580
-
581
- if (value < 0) {
582
- this._currentItem = 0;
583
- } else if (value >= this.dom.carouselItems.length) {
584
- this._currentItem = this.dom.carouselItems.length - 1;
585
- } else {
586
- this._currentItem = value;
587
- }
588
-
589
- // Keep the aria selected in sync with the current item.
590
- const tabs = this._dom.carousel.querySelectorAll(
591
- this.selectors.carouselTab
592
- );
593
- if (tabs) {
594
- this.dom.carouselItems.forEach((item, index) => {
595
- item.setAttribute("aria-selected", index === this._currentItem);
596
- });
597
- }
598
- }
599
-
600
- set autoplay(value) {
601
- isValidType("boolean", { value });
602
-
603
- if (this._autoplay !== value) {
604
- this._autoplay = value;
605
- }
606
- }
607
-
608
- set activeClass(value) {
609
- isValidClassList({ activeClass: value });
610
-
611
- if (this._activeClass !== value) {
612
- this._activeClass = value;
613
- }
614
- }
615
-
616
- set previousClass(value) {
617
- isValidClassList({ previousClass: value });
618
-
619
- if (this._previousClass !== value) {
620
- this._previousClass = value;
621
- }
622
- }
623
-
624
- set nextClass(value) {
625
- isValidClassList({ nextClass: value });
626
-
627
- if (this._nextClass !== value) {
628
- this._nextClass = value;
629
- }
630
- }
631
-
632
- set playClass(value) {
633
- isValidClassList({ playClass: value });
634
-
635
- if (this._playClass !== value) {
636
- this._playClass = value;
637
- }
638
- }
639
-
640
- set pauseClass(value) {
641
- isValidClassList({ pauseClass: value });
642
-
643
- if (this._pauseClass !== value) {
644
- this._pauseClass = value;
645
- }
646
- }
647
-
648
- set transitionDelay(value) {
649
- isValidType("number", { value });
650
-
651
- if (value !== this.transitionDelay && value >= 0) {
652
- this._currentItem = value;
653
- }
654
- }
655
-
656
- set transitionDuration(value) {
657
- isValidType("number", { value });
658
-
659
- if (this._transitionDuration !== value && value >= 0) {
660
- this._transitionDuration = value;
661
- this._setTransitionDuration();
662
- }
663
- }
664
-
665
- set playText(value) {
666
- isValidType("string", { value });
667
-
668
- if (this._playText !== value) {
669
- this._playText = value;
670
- }
671
- }
672
-
673
- set pauseText(value) {
674
- isValidType("string", { value });
675
-
676
- if (this._pauseText !== value) {
677
- this._pauseText = value;
678
- }
679
- }
680
-
681
- set prefix(value) {
682
- isValidType("string", { value });
683
-
684
- if (this._prefix !== value) {
685
- this._prefix = value;
686
- }
687
- }
688
-
689
- set key(value) {
690
- isValidType("string", { value });
691
-
692
- if (this._key !== value) {
693
- this._key = value;
694
- }
695
- }
696
-
697
- /**
698
- * Validates all aspects of the carousel to ensure proper functionality.
699
- *
700
- * @protected
701
- *
702
- * @return {boolean} - The results of the validation.
703
- */
704
- _validate() {
705
- let check = true;
706
-
707
- // HTML element checks.
708
- const htmlElementChecks = isValidInstance(HTMLElement, {
709
- carousel: this.dom.carousel,
710
- });
711
-
712
- if (!htmlElementChecks) {
713
- this._errors.push(htmlElementChecks.message);
714
- check = false;
715
- }
716
-
717
- // Query selector checks.
718
- const querySelectorChecks = isQuerySelector({
719
- carouselItemsSelector: this._selectors.carouselItems,
720
- carouselItemContainerSelector: this._selectors.carouselItemContainer,
721
- carouselControlsSelector: this._selectors.carouselControls,
722
- carouselControlContainerSelector:
723
- this._selectors.carouselControlContainer,
724
- carouselTabsSelector: this._selectors.carouselTabs,
725
- carouselTabContainerSelector: this._selectors.carouselTabContainer,
726
- autoplaySelector: this._selectors.autoplay,
727
- nextSelector: this._selectors.next,
728
- previousSelector: this._selectors.previous,
729
- });
730
-
731
- if (!querySelectorChecks) {
732
- this._errors.push(querySelectorChecks.message);
733
- check = false;
734
- }
735
-
736
- // Autoplay checks.
737
- const autoplayChecks = isValidType("boolean", { autoplay: this.autoplay });
738
-
739
- if (!autoplayChecks) {
740
- this._errors.push(autoplayChecks.message);
741
- check = false;
742
- }
743
-
744
- // Check delay is a valid value.
745
- const delayCheck = isValidType("number", {
746
- transitionDelay: this._transitionDelay,
747
- });
748
-
749
- if (!delayCheck) {
750
- this._errors.push(delayCheck.message);
751
- check = false;
752
- }
753
-
754
- // Check duration is a valid value.
755
- const durationCheck = isValidType("number", {
756
- transitionDuration: this._transitionDuration,
757
- });
758
-
759
- if (!durationCheck) {
760
- this._errors.push(durationCheck.message);
761
- check = false;
762
- }
763
-
764
- // Active class checks.
765
- if (this._activeClass !== "") {
766
- const activeClassChecks = isValidClassList({
767
- activeClass: this._activeClass,
768
- });
769
-
770
- if (!activeClassChecks) {
771
- this._errors.push(activeClassChecks.message);
772
- check = false;
773
- }
774
- }
775
-
776
- // Previous class checks.
777
- if (this._previousClass !== "") {
778
- const previousClassChecks = isValidClassList({
779
- previousClass: this._previousClass,
780
- });
781
-
782
- if (!previousClassChecks) {
783
- this._errors.push(previousClassChecks.message);
784
- check = false;
785
- }
786
- }
787
-
788
- // Next class checks.
789
- if (this._nextClass !== "") {
790
- const nextClassChecks = isValidClassList({
791
- nextClass: this._nextClass,
792
- });
793
-
794
- if (!nextClassChecks) {
795
- this._errors.push(nextClassChecks.message);
796
- check = false;
797
- }
798
- }
799
-
800
- // Play class checks.
801
- if (this._playClass !== "") {
802
- const playClassChecks = isValidClassList({
803
- playClass: this._playClass,
804
- });
805
-
806
- if (!playClassChecks) {
807
- this._errors.push(playClassChecks.message);
808
- check = false;
809
- }
810
- }
811
-
812
- // Pause class checks.
813
- if (this._pauseClass !== "") {
814
- const pauseClassChecks = isValidClassList({
815
- pauseClass: this._pauseClass,
816
- });
817
-
818
- if (!pauseClassChecks) {
819
- this._errors.push(pauseClassChecks.message);
820
- check = false;
821
- }
822
- }
823
-
824
- // Play text checks.
825
- if (this._playText !== "") {
826
- const playTextChecks = isValidType("string", {
827
- playText: this._playText,
828
- });
829
-
830
- if (!playTextChecks) {
831
- this._errors.push(playTextChecks.message);
832
- check = false;
833
- }
834
- }
835
-
836
- // Pause text checks.
837
- if (this._pauseText !== "") {
838
- const pauseTextChecks = isValidType("string", {
839
- pauseText: this._pauseText,
840
- });
841
-
842
- if (!pauseTextChecks) {
843
- this._errors.push(pauseTextChecks.message);
844
- check = false;
845
- }
846
- }
847
-
848
- // Prefix checks.
849
- const prefixChecks = isValidType("string", { prefix: this._prefix });
850
-
851
- if (!prefixChecks) {
852
- this._errors.push(prefixChecks.message);
853
- check = false;
854
- }
855
-
856
- return check;
857
- }
858
-
859
- /**
860
- * Sets DOM elements within the carousel.
861
- *
862
- * The carousel element _cannot_ be set through this method.
863
- *
864
- * @protected
865
- *
866
- * @param {string} elementType - The type of element to populate.
867
- * @param {HTMLElement} [base = this.dom.carousel] - The element used as the base for the querySelector.
868
- * @param {boolean} [overwrite = true] - A flag to set if the existing elements will be overwritten.
869
- */
870
- _setDOMElementType(elementType, base = this.dom.carousel, overwrite = true) {
871
- if (typeof this.selectors[elementType] === "string") {
872
- if (elementType === "carousel") {
873
- throw new Error(
874
- `Graupl Carousel: "${elementType}" element cannot be set through _setDOMElementType.`
875
- );
876
- }
877
-
878
- if (base !== this.dom.carousel) isValidInstance(HTMLElement, { base });
879
-
880
- if (Array.isArray(this._dom[elementType])) {
881
- // Get all the elements matching the selector in the base.
882
- const domElements = Array.from(
883
- base.querySelectorAll(this.selectors[elementType])
884
- );
885
-
886
- // Filter the elements so only direct children of the base are kept.
887
- const filteredElements = domElements.filter(
888
- (item) => item.parentElement === base
889
- );
890
-
891
- if (overwrite) {
892
- this._dom[elementType] = filteredElements;
893
- } else {
894
- this._dom[elementType] = [
895
- ...this._dom[elementType],
896
- ...filteredElements,
897
- ];
898
- }
899
- } else {
900
- // Get the single element matching the selector in the base.
901
- const domElement = base.querySelector(this.selectors[elementType]);
902
-
903
- // Ensure the element is a direct child of the base.
904
- if (domElement && domElement.parentElement !== base) {
905
- return;
906
- }
907
-
908
- if (overwrite) {
909
- this._dom[elementType] = domElement;
910
- }
911
- }
912
- } else {
913
- throw new Error(
914
- `Graupl Carousel: "${elementType}" is not a valid element type within the carousel.`
915
- );
916
- }
917
- }
918
-
919
- /**
920
- * Resets DOM elements within the menu.
921
- *
922
- * The carousel element _cannot_ be reset through this method.
923
- *
924
- * @protected
925
- *
926
- * @param {string} elementType - The type of element to clear.
927
- */
928
- _resetDOMElementType(elementType) {
929
- if (typeof this.selectors[elementType] === "string") {
930
- if (elementType === "carousel") {
931
- throw new Error(
932
- `Graupl Carousel: "${elementType}" element cannot be reset through _resetDOMElementType.`
933
- );
934
- }
935
-
936
- if (Array.isArray(this._dom[elementType])) {
937
- this._dom[elementType] = [];
938
- } else {
939
- this._dom[elementType] = null;
940
- }
941
- } else {
942
- throw new Error(
943
- `Graupl Carousel: "${elementType}" is not a valid element type within the carousel.`
944
- );
945
- }
946
- }
947
-
948
- /**
949
- * Sets all DOM elements within the carousel.
950
- *
951
- * Utilizes _setDOMElementType and _resetDOMElementType.
952
- *
953
- * @protected
954
- */
955
- _setDOMElements() {
956
- this._setDOMElementType("carouselItemContainer");
957
- this._setDOMElementType("carouselControlContainer");
958
- this._setDOMElementType("carouselTabContainer");
959
-
960
- if (this.dom.carouselItemContainer) {
961
- this._setDOMElementType("carouselItems", this.dom.carouselItemContainer);
962
- }
963
- if (this.dom.carouselControlContainer) {
964
- this._setDOMElementType(
965
- "carouselControls",
966
- this.dom.carouselControlContainer
967
- );
968
- this._setDOMElementType("autoplay", this.dom.carouselControlContainer);
969
- this._setDOMElementType("next", this.dom.carouselControlContainer);
970
- this._setDOMElementType("previous", this.dom.carouselControlContainer);
971
- }
972
-
973
- if (this._dom.carouselTabContainer) {
974
- this._setDOMElementType("carouselTabs", this.dom.carouselTabContainer);
975
- }
976
- }
977
-
978
- /**
979
- * Generates a key for the carousel.
980
- *
981
- * @param {boolean} [regenerate = false] - A flag to determine if the key should be regenerated.
982
- */
983
- _generateKey(regenerate = false) {
984
- if (this.key === "" || regenerate) {
985
- this.key = Math.random()
986
- .toString(36)
987
- .replace(/[^a-z]+/g, "")
988
- .substring(0, 10);
989
- }
990
- }
991
-
992
- /**
993
- * Sets the IDs of the carousel and it's children if they do not already exist.
994
- *
995
- * The generated IDs use the key and follow the format:
996
- * - carousel: `carousel-${key}`
997
- * - carousel items: `carousel-item-${key}-${index}`
998
- * - carousel tabs: `carousel-tab-${key}-${index}`
999
- */
1000
- _setIds() {
1001
- this.dom.carousel.id = this.dom.carousel.id || `carousel-${this.key}`;
1002
-
1003
- this.dom.carouselItems.forEach((item, index) => {
1004
- item.id = item.id || `carousel-item-${this.key}-${index}`;
1005
- });
1006
-
1007
- this.dom.carouselTabs.forEach((tab, index) => {
1008
- tab.id = tab.id || `carousel-tab-${this.key}-${index}`;
1009
- });
1010
- }
1011
-
1012
- /**
1013
- * Sets the aria attributes for the carousel.
1014
- */
1015
- _setAriaAttributes() {
1016
- // Make sure the carousel has a proper role.
1017
- // Sections and role="region" are acceptable in certain cases, so
1018
- // we only need to fallback to role="group" if neither of those are present.
1019
- if (
1020
- !isTag("section", { carousel: this.dom.carousel }) &&
1021
- !this.dom.carousel.getAttribute("role") !== "region"
1022
- ) {
1023
- this.dom.carousel.setAttribute("role", "group");
1024
- }
1025
-
1026
- // Set the role description for the carousel.
1027
- this._dom.carousel.setAttribute("aria-roledescription", "carousel");
1028
-
1029
- if (this.dom.carouselTabContainer) {
1030
- this.dom.carouselTabContainer.setAttribute("role", "tablist");
1031
- }
1032
-
1033
- this.dom.carouselTabs.forEach((tab, index) => {
1034
- if (!isTag("button", { tab: tab })) {
1035
- tab.setAttribute("role", "button");
1036
- }
1037
-
1038
- tab.setAttribute("aria-selected", index === 0);
1039
- tab.setAttribute("aria-controls", this.dom.carouselItems[index].id);
1040
- });
1041
- }
1042
-
1043
- /**
1044
- * Sets the interval for autoplaying the carousel.
1045
- *
1046
- * @protected
1047
- */
1048
- _setInterval() {
1049
- this._clearInterval();
1050
-
1051
- this._autoplayInterval = setInterval(() => {
1052
- this.activateNextItem();
1053
- }, this.transitionDelay);
1054
- }
1055
-
1056
- /**
1057
- * Clears the interval for autoplaying the carousel.
1058
- *
1059
- * @protected
1060
- */
1061
- _clearInterval() {
1062
- clearInterval(this._autoplayInterval);
1063
- }
1064
-
1065
- /**
1066
- * Handles the autoplay functionality of the carousel.
1067
- *
1068
- * - Adds the appropriate class to the autoplay button.
1069
- * - Removes the appropriate class from the autoplay button.
1070
- * - Sets the appropriate aria-label for the autoplay button.
1071
- * - Sets the appropriate aria-live for the carousel.
1072
- * - Sets/clears the interval for autoplaying the carousel.
1073
- *
1074
- * @protected
1075
- */
1076
- _handleAutoplay() {
1077
- if (this.autoplay) {
1078
- addClass(this.pauseClass, this.dom.autoplay);
1079
- removeClass(this.playClass, this.dom.autoplay);
1080
-
1081
- this.dom.autoplay.setAttribute("aria-label", this.pauseText);
1082
- this.dom.carousel.setAttribute("aria-live", "off");
1083
-
1084
- this._setInterval();
1085
- } else {
1086
- addClass(this.playClass, this.dom.autoplay);
1087
- removeClass(this.pauseClass, this.dom.autoplay);
1088
-
1089
- this.dom.autoplay.setAttribute("aria-label", this.playText);
1090
- this.dom.carousel.setAttribute("aria-live", "polite");
1091
-
1092
- this._clearInterval();
1093
- }
1094
- }
1095
-
1096
- /**
1097
- * Handles the focus events throughout the carousel for proper use.
1098
- *
1099
- * - Adds a `focusin` listener to the carousel element to pause autoplay.
1100
- * - Adds a `focusout` listener to the carousel element to resume autoplay.
1101
- */
1102
- _handleFocus() {
1103
- // Pause autoplay when anything in the carousel is focused.
1104
- this.dom.carousel.addEventListener("focusin", () => {
1105
- if (this.autoplay) {
1106
- this._clearInterval();
1107
- }
1108
- });
1109
-
1110
- this.dom.carousel.addEventListener("focusout", () => {
1111
- if (this.autoplay) {
1112
- this._setInterval();
1113
- }
1114
- });
1115
- }
1116
-
1117
- /**
1118
- * Handles the click events throughout the carousel.
1119
- *
1120
- * - Adds a `pointerup` listener to the next control to activate the next item.
1121
- * - Adds a `pointerup` listener to the previous control to activate the previous item.
1122
- * - Adds a `pointerup` listener to the autoplay control to toggle autoplay.
1123
- * - Adds a `pointerup` listener to each tab control to activate the corresponding item.
1124
- */
1125
- _handleClick() {
1126
- this.dom.next.addEventListener("pointerup", () => {
1127
- this.activateNextItem();
1128
- });
1129
-
1130
- this.dom.previous.addEventListener("pointerup", () => {
1131
- this.activatePreviousItem();
1132
- });
1133
-
1134
- this.dom.autoplay.addEventListener("pointerup", () => {
1135
- this.toggleAutoplay();
1136
- });
1137
-
1138
- this.dom.carouselTabs.forEach((tab, index) => {
1139
- tab.addEventListener("pointerup", () => {
1140
- if (this.currentItem > index) {
1141
- this._currentAction = "previous";
1142
- } else {
1143
- this._currentAction = "next";
1144
- }
1145
-
1146
- this.activateItem(index);
1147
- });
1148
- });
1149
- }
1150
-
1151
- /**
1152
- * Handles the hover events throughout the carousel for proper use.
1153
- *
1154
- * - Adds a `pointerover` listener to the carousel to pause autoplay.
1155
- * - Adds a `pointerleave` listener to the carousel to resume autoplay.
1156
- */
1157
- _handleHover() {
1158
- // Pause autoplay when anything in the carousel is hovered.
1159
- this.dom.carousel.addEventListener("pointerover", () => {
1160
- if (this.autoplay) {
1161
- this._clearInterval();
1162
- }
1163
- });
1164
-
1165
- this.dom.carousel.addEventListener("pointerleave", () => {
1166
- if (this.autoplay) {
1167
- this._setInterval();
1168
- }
1169
- });
1170
- }
1171
-
1172
- /**
1173
- * Handles keydown events throughout the carousel item for proper use.
1174
- *
1175
- * - Adds a `keydown` listener to all control elements.
1176
- * - Prevents Space and Enter key events.
1177
- * - Adds a `keydown` listener to all tab elements.
1178
- * - Prevents Space and Enter key events.
1179
- */
1180
- _handleKeydown() {
1181
- this.dom.carouselControls.forEach((control) => {
1182
- control.addEventListener("keydown", (event) => {
1183
- const key = keyPress(event);
1184
-
1185
- switch (key) {
1186
- case "Space":
1187
- case "Enter":
1188
- // Prevent the default action of the event.
1189
- preventEvent(event);
1190
-
1191
- break;
1192
- }
1193
- });
1194
- });
1195
-
1196
- this.dom.carouselTabs.forEach((tab) => {
1197
- tab.addEventListener("keydown", (event) => {
1198
- const key = keyPress(event);
1199
-
1200
- switch (key) {
1201
- case "Space":
1202
- case "Enter":
1203
- // Prevent the default action of the event.
1204
- preventEvent(event);
1205
-
1206
- break;
1207
- }
1208
- });
1209
- });
1210
- }
1211
-
1212
- /**
1213
- * Handles keyup events throughout the carousel item for proper use.
1214
- *
1215
- * - Adds a `keyup` listener to all control elements.
1216
- * - Activates the next/previous item depending on which control is pressed.
1217
- * - Toggles autoplay if the autoplay control is pressed.
1218
- *
1219
- */
1220
- _handleKeyup() {
1221
- // Activate the next item if the space or enter key on the next control.
1222
- this.dom.next.addEventListener("keyup", (event) => {
1223
- const key = keyPress(event);
1224
-
1225
- switch (key) {
1226
- case "Space":
1227
- case "Enter":
1228
- this.activateNextItem();
1229
-
1230
- // Prevent the default action of the event.
1231
- preventEvent(event);
1232
-
1233
- break;
1234
- }
1235
- });
1236
-
1237
- // Activate the previous item if the space or enter key on the previous control.
1238
- this.dom.previous.addEventListener("keyup", (event) => {
1239
- const key = keyPress(event);
1240
-
1241
- switch (key) {
1242
- case "Space":
1243
- case "Enter":
1244
- this.activatePreviousItem();
1245
-
1246
- // Prevent the default action of the event.
1247
- preventEvent(event);
1248
-
1249
- break;
1250
- }
1251
- });
1252
-
1253
- // Toggle autoplay if the space or enter key on the autoplay control.
1254
- this.dom.autoplay.addEventListener("keyup", (event) => {
1255
- const key = keyPress(event);
1256
-
1257
- switch (key) {
1258
- case "Space":
1259
- case "Enter":
1260
- this.toggleAutoplay();
1261
-
1262
- // Prevent the default action of the event.
1263
- preventEvent(event);
1264
-
1265
- break;
1266
- }
1267
- });
1268
-
1269
- // Activate the item if the space or enter key on the tab control.
1270
- this.dom.carouselTabs.forEach((tab, index) => {
1271
- tab.addEventListener("keyup", (event) => {
1272
- const key = keyPress(event);
1273
-
1274
- switch (key) {
1275
- case "Space":
1276
- case "Enter":
1277
- this.activateItem(index);
1278
-
1279
- // Prevent the default action of the event.
1280
- preventEvent(event);
1281
-
1282
- break;
1283
- }
1284
- });
1285
- });
1286
- }
1287
-
1288
- /**
1289
- * Sets the transition duration for the carousel as a CSS custom property.
1290
- *
1291
- * The custom property is set as `--graupl-carousel-transition-duration`.
1292
- *
1293
- * @protected
1294
- */
1295
- _setTransitionDuration() {
1296
- this.dom.carousel.style.setProperty(
1297
- `--${this.prefix}carousel-transition-duration`,
1298
- `${this.transitionDuration}ms`
1299
- );
1300
- }
1301
-
1302
- /**
1303
- * Activates the current carousel item.
1304
- *
1305
- * @public
1306
- */
1307
- activateCurrentItem() {
1308
- addClass(this.activeClass, this.currentCarouselItem);
1309
-
1310
- if (this.currentCarouselTab) {
1311
- this.currentCarouselTab.setAttribute("aria-selected", true);
1312
- addClass(this.activeClass, this.currentCarouselTab);
1313
- }
1314
- }
1315
-
1316
- /**
1317
- * Deactivates the current carousel item.
1318
- *
1319
- * @public
1320
- */
1321
- deactivateCurrentItem() {
1322
- removeClass(this.activeClass, this.currentCarouselItem);
1323
-
1324
- if (this.currentCarouselTab) {
1325
- this.currentCarouselTab.setAttribute("aria-selected", false);
1326
- removeClass(this.activeClass, this.currentCarouselTab);
1327
- }
1328
- }
1329
-
1330
- /**
1331
- * Activates the carousel item at a given index.
1332
- *
1333
- * @public
1334
- *
1335
- * @param {number} index - The index of the carousel item to activate.
1336
- */
1337
- activateItem(index) {
1338
- const currentIndex = this.currentItem;
1339
-
1340
- this.dom.carousel.dataset.grauplAction = this._currentAction;
1341
-
1342
- if (this.autoplay) {
1343
- this._clearInterval();
1344
- }
1345
-
1346
- addClass(this.previousClass, this.currentCarouselItem);
1347
- addClass(this.nextClass, this.dom.carouselItems[index]);
1348
-
1349
- requestAnimationFrame(() => {
1350
- this.deactivateCurrentItem();
1351
- this.currentItem = index;
1352
- this.activateCurrentItem();
1353
-
1354
- requestAnimationFrame(() => {
1355
- setTimeout(() => {
1356
- removeClass(this.previousClass, this.dom.carouselItems[currentIndex]);
1357
- removeClass(this.nextClass, this.currentCarouselItem);
1358
- }, this.transitionDuration);
1359
- });
1360
- });
1361
-
1362
- if (this.autoplay) {
1363
- this._setInterval();
1364
- }
1365
- }
1366
-
1367
- /**
1368
- * Activates the first carousel item.
1369
- *
1370
- * @public
1371
- */
1372
- activateFirstItem() {
1373
- this.activateItem(0);
1374
- }
1375
-
1376
- /**
1377
- * Activates the last carousel item.
1378
- *
1379
- * @public
1380
- */
1381
- activateLastItem() {
1382
- this.activateItem(this.dom.carouselItems.length - 1);
1383
- }
1384
-
1385
- /**
1386
- * Activates the next carousel item.
1387
- *
1388
- * @public
1389
- */
1390
- activateNextItem() {
1391
- this._currentAction = "next";
1392
-
1393
- if (this.currentItem + 1 >= this.dom.carouselItems.length) {
1394
- this.activateFirstItem();
1395
- } else {
1396
- this.activateItem(this.currentItem + 1);
1397
- }
1398
- }
1399
-
1400
- /**
1401
- * Activates the previous carousel item.
1402
- *
1403
- * @public
1404
- */
1405
- activatePreviousItem() {
1406
- this._currentAction = "previous";
1407
-
1408
- if (this.currentItem - 1 < 0) {
1409
- this.activateLastItem();
1410
- } else {
1411
- this.activateItem(this.currentItem - 1);
1412
- }
1413
- }
1414
-
1415
- /**
1416
- * Toggles autoplay on the carousel.
1417
- *
1418
- * @public
1419
- */
1420
- toggleAutoplay() {
1421
- this.autoplay = !this.autoplay;
1422
-
1423
- this._handleAutoplay();
1424
- }
1425
- }
1426
-
1427
- export default Carousel;