@expressivecss/expressive 0.14.1 → 0.15.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 (242) hide show
  1. package/CHANGELOG.md +88 -1
  2. package/README.md +1 -1
  3. package/dist/css/expressive.css +200 -241
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/js/chunks/{chunk-4KMNFIFZ.mjs → chunk-33QVDDGR.mjs} +3 -3
  8. package/dist/js/chunks/{chunk-SPETGK25.mjs → chunk-45FER6RI.mjs} +5 -5
  9. package/dist/js/chunks/chunk-45FER6RI.mjs.map +7 -0
  10. package/dist/js/chunks/{chunk-GIW4K4SE.mjs → chunk-5CEAOLUA.mjs} +11 -10
  11. package/dist/js/chunks/{chunk-GIW4K4SE.mjs.map → chunk-5CEAOLUA.mjs.map} +2 -2
  12. package/dist/js/chunks/{chunk-LRZMJZ3T.mjs → chunk-6VATUZC6.mjs} +10 -6
  13. package/dist/js/chunks/chunk-6VATUZC6.mjs.map +7 -0
  14. package/dist/js/chunks/{chunk-QDAL4IYN.mjs → chunk-74MXKKLN.mjs} +2 -2
  15. package/dist/js/chunks/{chunk-QDAL4IYN.mjs.map → chunk-74MXKKLN.mjs.map} +2 -2
  16. package/dist/js/chunks/{chunk-CUQPB25U.mjs → chunk-AIURVCG6.mjs} +3 -3
  17. package/dist/js/chunks/{chunk-KHV6DZXX.mjs → chunk-BGZLF6JZ.mjs} +16 -16
  18. package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +7 -0
  19. package/dist/js/chunks/{chunk-BG6ZRB5H.mjs → chunk-C6CHEWYP.mjs} +2 -2
  20. package/dist/js/chunks/{chunk-GVGT6MIU.mjs → chunk-CK2XCICY.mjs} +2 -2
  21. package/dist/js/chunks/{chunk-KY6U46SM.mjs → chunk-CXXM2L4F.mjs} +8 -9
  22. package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +7 -0
  23. package/dist/js/chunks/{chunk-Z2NRKI7R.mjs → chunk-DXGRXYYL.mjs} +25 -37
  24. package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +7 -0
  25. package/dist/js/chunks/{chunk-MZ6Z24BX.mjs → chunk-FM5CZOUB.mjs} +3 -7
  26. package/dist/js/chunks/{chunk-MZ6Z24BX.mjs.map → chunk-FM5CZOUB.mjs.map} +2 -2
  27. package/dist/js/chunks/{chunk-5HQSGDZ5.mjs → chunk-GJL6GCIU.mjs} +34 -55
  28. package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +7 -0
  29. package/dist/js/chunks/chunk-K3HZMFMD.mjs +135 -0
  30. package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +7 -0
  31. package/dist/js/chunks/{chunk-TBM3FT7G.mjs → chunk-KHXZ2A4K.mjs} +12 -15
  32. package/dist/js/chunks/{chunk-TBM3FT7G.mjs.map → chunk-KHXZ2A4K.mjs.map} +2 -2
  33. package/dist/js/chunks/chunk-KQACNQ22.mjs +7 -0
  34. package/dist/js/chunks/{chunk-KBNN3QDH.mjs.map → chunk-KQACNQ22.mjs.map} +1 -1
  35. package/dist/js/chunks/{chunk-UEXCIMJZ.mjs → chunk-KUFHW3DS.mjs} +2 -2
  36. package/dist/js/chunks/{chunk-A7ALMYUR.mjs → chunk-KVJAVDBC.mjs} +7 -15
  37. package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +7 -0
  38. package/dist/js/chunks/{chunk-YDCS5S3J.mjs → chunk-L27Q6ZMI.mjs} +2 -2
  39. package/dist/js/chunks/{chunk-NS2UMNZV.mjs → chunk-LQWUDNHZ.mjs} +3 -3
  40. package/dist/js/chunks/{chunk-MNPROCZF.mjs → chunk-M372EDXD.mjs} +4 -10
  41. package/dist/js/chunks/chunk-M372EDXD.mjs.map +7 -0
  42. package/dist/js/chunks/{chunk-YMSXJON6.mjs → chunk-M3MURWMB.mjs} +15 -12
  43. package/dist/js/chunks/{chunk-YMSXJON6.mjs.map → chunk-M3MURWMB.mjs.map} +2 -2
  44. package/dist/js/chunks/{chunk-JIDMQGK6.mjs → chunk-NUHMOAOY.mjs} +18 -33
  45. package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +7 -0
  46. package/dist/js/chunks/{chunk-VGZSAFTX.mjs → chunk-OWG3LMUL.mjs} +7 -11
  47. package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +7 -0
  48. package/dist/js/chunks/{chunk-LTWPGFBR.mjs → chunk-PD6HYHAE.mjs} +4 -15
  49. package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +7 -0
  50. package/dist/js/chunks/{chunk-ZAS25YFD.mjs → chunk-PDG64UHF.mjs} +3 -3
  51. package/dist/js/chunks/{chunk-QERLECVU.mjs → chunk-PO3AXVR3.mjs} +38 -64
  52. package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +7 -0
  53. package/dist/js/chunks/{chunk-ILP3PDTL.mjs → chunk-QYGK36OG.mjs} +7 -13
  54. package/dist/js/chunks/chunk-QYGK36OG.mjs.map +7 -0
  55. package/dist/js/chunks/{chunk-S3XDFGSZ.mjs → chunk-SFI2U4YW.mjs} +28 -44
  56. package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +7 -0
  57. package/dist/js/chunks/{chunk-FS7XY3HT.mjs → chunk-SMY7GJSS.mjs} +3 -3
  58. package/dist/js/chunks/{chunk-O5XPWXIQ.mjs → chunk-TCCA2HDG.mjs} +39 -31
  59. package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +7 -0
  60. package/dist/js/chunks/{chunk-PM655FXL.mjs → chunk-TSZYSW7F.mjs} +4 -4
  61. package/dist/js/chunks/{chunk-PM655FXL.mjs.map → chunk-TSZYSW7F.mjs.map} +2 -2
  62. package/dist/js/chunks/{chunk-UEZUJQ66.mjs → chunk-UAZSDUVP.mjs} +3 -4
  63. package/dist/js/chunks/{chunk-UEZUJQ66.mjs.map → chunk-UAZSDUVP.mjs.map} +2 -2
  64. package/dist/js/chunks/{chunk-6N2XAEFK.mjs → chunk-UBRZZWRA.mjs} +10 -8
  65. package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +7 -0
  66. package/dist/js/chunks/{chunk-5BKHWHYY.mjs → chunk-UCOE7ZDL.mjs} +41 -46
  67. package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +7 -0
  68. package/dist/js/chunks/{chunk-4TKTLGEM.mjs → chunk-UETTGDLI.mjs} +3 -3
  69. package/dist/js/chunks/{chunk-RHRQKTTX.mjs → chunk-UNCRDLP6.mjs} +6 -9
  70. package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +7 -0
  71. package/dist/js/chunks/{chunk-GUB3TNO2.mjs → chunk-VGNYF6FB.mjs} +3 -6
  72. package/dist/js/chunks/{chunk-GUB3TNO2.mjs.map → chunk-VGNYF6FB.mjs.map} +2 -2
  73. package/dist/js/chunks/{chunk-X7OCHZVF.mjs → chunk-VGPGBNGL.mjs} +4 -12
  74. package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +7 -0
  75. package/dist/js/chunks/chunk-VKAUVTQY.mjs +1 -0
  76. package/dist/js/chunks/{chunk-HKT2S7VM.mjs → chunk-VM4FTS7L.mjs} +3 -3
  77. package/dist/js/chunks/{chunk-3GVFZ4XO.mjs → chunk-WDK4T63U.mjs} +8 -11
  78. package/dist/js/chunks/chunk-WDK4T63U.mjs.map +7 -0
  79. package/dist/js/chunks/{chunk-GZKEFWPM.mjs → chunk-WOCCTVUF.mjs} +38 -34
  80. package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +7 -0
  81. package/dist/js/chunks/{chunk-QJABDLSD.mjs → chunk-WQYN5L4E.mjs} +11 -16
  82. package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +7 -0
  83. package/dist/js/chunks/{chunk-DAIU5SLG.mjs → chunk-X4ISMKE2.mjs} +2 -2
  84. package/dist/js/chunks/{chunk-3DHK5CZU.mjs → chunk-XAEAEHIX.mjs} +6 -8
  85. package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +7 -0
  86. package/dist/js/chunks/{chunk-4HZMB7LI.mjs → chunk-ZX6M7SWO.mjs} +24 -24
  87. package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +7 -0
  88. package/dist/js/expressive.cjs +484 -507
  89. package/dist/js/expressive.cjs.map +4 -4
  90. package/dist/js/expressive.js +484 -507
  91. package/dist/js/expressive.js.map +4 -4
  92. package/dist/js/expressive.min.js +10 -13
  93. package/dist/js/expressive.min.js.map +4 -4
  94. package/dist/js/expressive.mjs +54 -50
  95. package/dist/js/expressive.mjs.map +1 -1
  96. package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
  97. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  98. package/dist/js/internal/behaviors/forms.mjs +2 -2
  99. package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
  100. package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
  101. package/dist/js/internal/components/appBar.mjs +2 -2
  102. package/dist/js/internal/components/autocomplete.mjs +4 -4
  103. package/dist/js/internal/components/barChart.mjs +4 -4
  104. package/dist/js/internal/components/buttonGroup.mjs +2 -2
  105. package/dist/js/internal/components/buttons.mjs +3 -3
  106. package/dist/js/internal/components/cards.mjs +3 -3
  107. package/dist/js/internal/components/carousel.mjs +3 -3
  108. package/dist/js/internal/components/characterCounter.mjs +2 -2
  109. package/dist/js/internal/components/chips.mjs +5 -5
  110. package/dist/js/internal/components/columnChart.mjs +3 -3
  111. package/dist/js/internal/components/commandPalette.mjs +3 -3
  112. package/dist/js/internal/components/confetti.mjs +2 -2
  113. package/dist/js/internal/components/datepicker.mjs +6 -6
  114. package/dist/js/internal/components/expandingCard.mjs +3 -3
  115. package/dist/js/internal/components/heatmapChart.mjs +3 -3
  116. package/dist/js/internal/components/index.mjs +47 -43
  117. package/dist/js/internal/components/keypad.mjs +9 -0
  118. package/dist/js/internal/components/keypad.mjs.map +7 -0
  119. package/dist/js/internal/components/lightbox.mjs +3 -3
  120. package/dist/js/internal/components/lineChart.mjs +6 -2
  121. package/dist/js/internal/components/mapView.mjs +3 -3
  122. package/dist/js/internal/components/menu.mjs +3 -3
  123. package/dist/js/internal/components/messageScroller.mjs +3 -3
  124. package/dist/js/internal/components/mixedChart.mjs +4 -4
  125. package/dist/js/internal/components/navigationRail.mjs +2 -2
  126. package/dist/js/internal/components/particles.mjs +2 -2
  127. package/dist/js/internal/components/pieChart.mjs +3 -3
  128. package/dist/js/internal/components/questionnaire.mjs +3 -3
  129. package/dist/js/internal/components/radarChart.mjs +3 -3
  130. package/dist/js/internal/components/radialChart.mjs +3 -3
  131. package/dist/js/internal/components/registry.mjs +41 -40
  132. package/dist/js/internal/components/richTextEditor.mjs +3 -3
  133. package/dist/js/internal/components/scrollspy.mjs +2 -2
  134. package/dist/js/internal/components/select.mjs +4 -4
  135. package/dist/js/internal/components/slider.mjs +3 -3
  136. package/dist/js/internal/components/snackbar.mjs +2 -2
  137. package/dist/js/internal/components/tabs.mjs +4 -4
  138. package/dist/js/internal/components/timepicker.mjs +4 -4
  139. package/dist/js/internal/components/tooltip.mjs +3 -3
  140. package/dist/js/internal/core/component.mjs +1 -1
  141. package/dist/js/internal/core/utils.mjs +1 -1
  142. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  143. package/dist/js/modular.mjs +54 -50
  144. package/dist/types/components/autocomplete.d.ts +1 -0
  145. package/dist/types/components/datepicker.d.ts +3 -4
  146. package/dist/types/components/expandingCard.d.ts +2 -0
  147. package/dist/types/components/index.d.ts +1 -0
  148. package/dist/types/components/keypad.d.ts +34 -0
  149. package/dist/types/components/lightbox.d.ts +3 -5
  150. package/dist/types/components/lineChart.d.ts +4 -0
  151. package/dist/types/components/menu.d.ts +1 -0
  152. package/dist/types/components/radialChart.d.ts +0 -1
  153. package/dist/types/components/registry.d.ts +4 -0
  154. package/dist/types/components/slider.d.ts +2 -0
  155. package/dist/types/components/snackbar.d.ts +1 -0
  156. package/dist/types/components/tabs.d.ts +4 -0
  157. package/dist/types/components/timepicker.d.ts +2 -0
  158. package/dist/types/modular.d.ts +1 -1
  159. package/dist/types/plugins/dockedDisplayPlugin.d.ts +1 -0
  160. package/package.json +1 -1
  161. package/src/sass/abstracts/_breakpoints.scss +0 -1
  162. package/src/sass/abstracts/_elevation.scss +1 -1
  163. package/src/sass/abstracts/_mixins.scss +20 -60
  164. package/src/sass/abstracts/_variables.scss +10 -0
  165. package/src/sass/base/_global.scss +3 -12
  166. package/src/sass/base/_index.scss +1 -1
  167. package/src/sass/components/_badges.scss +1 -8
  168. package/src/sass/components/_bar-chart.scss +1 -1
  169. package/src/sass/components/_button-groups.scss +31 -66
  170. package/src/sass/components/_cards.scss +6 -25
  171. package/src/sass/components/_carousel.scss +16 -55
  172. package/src/sass/components/_chips.scss +0 -6
  173. package/src/sass/components/_column-chart.scss +1 -1
  174. package/src/sass/components/_data-table.scss +1 -3
  175. package/src/sass/components/_datepicker.scss +3 -22
  176. package/src/sass/components/_dialog.scss +1 -4
  177. package/src/sass/components/_heatmap-chart.scss +2 -2
  178. package/src/sass/components/_icon-buttons.scss +0 -1
  179. package/src/sass/components/_index.scss +1 -0
  180. package/src/sass/components/_keypad.scss +162 -0
  181. package/src/sass/components/_lightbox.scss +3 -8
  182. package/src/sass/components/_map.scss +2 -2
  183. package/src/sass/components/_menu.scss +31 -74
  184. package/src/sass/components/_mixed-chart.scss +1 -1
  185. package/src/sass/components/_navbar.scss +9 -45
  186. package/src/sass/components/_navigation-rail.scss +23 -32
  187. package/src/sass/components/_page-footer.scss +15 -12
  188. package/src/sass/components/_panes.scss +2 -6
  189. package/src/sass/components/_progress.scss +6 -4
  190. package/src/sass/components/_side-sheet.scss +1 -4
  191. package/src/sass/components/_stepper.scss +0 -4
  192. package/src/sass/components/_timepicker.scss +4 -36
  193. package/src/sass/components/_toolbar.scss +0 -4
  194. package/src/sass/components/forms/_checkboxes.scss +37 -65
  195. package/src/sass/components/forms/_fieldset.scss +3 -3
  196. package/src/sass/components/forms/_file-input.scss +0 -1
  197. package/src/sass/components/forms/_radio-buttons.scss +10 -36
  198. package/src/sass/components/forms/_select.scss +0 -3
  199. package/src/sass/components/forms/_slider.scss +72 -259
  200. package/src/sass/tokens/_state.scss +2 -2
  201. package/src/sass/tokens/_theme.scss +1 -1
  202. package/src/sass/utilities/_colors.scss +6 -1
  203. package/src/sass/utilities/_index.scss +1 -1
  204. package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +0 -7
  205. package/dist/js/chunks/chunk-3GVFZ4XO.mjs.map +0 -7
  206. package/dist/js/chunks/chunk-4HZMB7LI.mjs.map +0 -7
  207. package/dist/js/chunks/chunk-5BKHWHYY.mjs.map +0 -7
  208. package/dist/js/chunks/chunk-5HQSGDZ5.mjs.map +0 -7
  209. package/dist/js/chunks/chunk-6N2XAEFK.mjs.map +0 -7
  210. package/dist/js/chunks/chunk-A7ALMYUR.mjs.map +0 -7
  211. package/dist/js/chunks/chunk-GZKEFWPM.mjs.map +0 -7
  212. package/dist/js/chunks/chunk-ILP3PDTL.mjs.map +0 -7
  213. package/dist/js/chunks/chunk-JIDMQGK6.mjs.map +0 -7
  214. package/dist/js/chunks/chunk-KBNN3QDH.mjs +0 -7
  215. package/dist/js/chunks/chunk-KHV6DZXX.mjs.map +0 -7
  216. package/dist/js/chunks/chunk-KY6U46SM.mjs.map +0 -7
  217. package/dist/js/chunks/chunk-LRZMJZ3T.mjs.map +0 -7
  218. package/dist/js/chunks/chunk-LTWPGFBR.mjs.map +0 -7
  219. package/dist/js/chunks/chunk-MNPROCZF.mjs.map +0 -7
  220. package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +0 -7
  221. package/dist/js/chunks/chunk-QERLECVU.mjs.map +0 -7
  222. package/dist/js/chunks/chunk-QJABDLSD.mjs.map +0 -7
  223. package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +0 -7
  224. package/dist/js/chunks/chunk-S3XDFGSZ.mjs.map +0 -7
  225. package/dist/js/chunks/chunk-SPETGK25.mjs.map +0 -7
  226. package/dist/js/chunks/chunk-VGZSAFTX.mjs.map +0 -7
  227. package/dist/js/chunks/chunk-X7OCHZVF.mjs.map +0 -7
  228. package/dist/js/chunks/chunk-Z2NRKI7R.mjs.map +0 -7
  229. package/dist/js/chunks/chunk-ZKZKNSLC.mjs +0 -1
  230. /package/dist/js/chunks/{chunk-4KMNFIFZ.mjs.map → chunk-33QVDDGR.mjs.map} +0 -0
  231. /package/dist/js/chunks/{chunk-CUQPB25U.mjs.map → chunk-AIURVCG6.mjs.map} +0 -0
  232. /package/dist/js/chunks/{chunk-BG6ZRB5H.mjs.map → chunk-C6CHEWYP.mjs.map} +0 -0
  233. /package/dist/js/chunks/{chunk-GVGT6MIU.mjs.map → chunk-CK2XCICY.mjs.map} +0 -0
  234. /package/dist/js/chunks/{chunk-UEXCIMJZ.mjs.map → chunk-KUFHW3DS.mjs.map} +0 -0
  235. /package/dist/js/chunks/{chunk-YDCS5S3J.mjs.map → chunk-L27Q6ZMI.mjs.map} +0 -0
  236. /package/dist/js/chunks/{chunk-NS2UMNZV.mjs.map → chunk-LQWUDNHZ.mjs.map} +0 -0
  237. /package/dist/js/chunks/{chunk-ZAS25YFD.mjs.map → chunk-PDG64UHF.mjs.map} +0 -0
  238. /package/dist/js/chunks/{chunk-FS7XY3HT.mjs.map → chunk-SMY7GJSS.mjs.map} +0 -0
  239. /package/dist/js/chunks/{chunk-4TKTLGEM.mjs.map → chunk-UETTGDLI.mjs.map} +0 -0
  240. /package/dist/js/chunks/{chunk-ZKZKNSLC.mjs.map → chunk-VKAUVTQY.mjs.map} +0 -0
  241. /package/dist/js/chunks/{chunk-HKT2S7VM.mjs.map → chunk-VM4FTS7L.mjs.map} +0 -0
  242. /package/dist/js/chunks/{chunk-DAIU5SLG.mjs.map → chunk-X4ISMKE2.mjs.map} +0 -0
@@ -39,6 +39,7 @@ __export(index_exports, {
39
39
  FormSelect: () => FormSelect,
40
40
  Forms: () => Forms,
41
41
  HeatmapChart: () => HeatmapChart,
42
+ Keypad: () => Keypad,
42
43
  Lightbox: () => Lightbox,
43
44
  LineChart: () => LineChart,
44
45
  MapView: () => MapView,
@@ -208,12 +209,7 @@ var _Utils = class _Utils {
208
209
  * @param trigger Trigger element.
209
210
  */
210
211
  static getIdFromTrigger(trigger) {
211
- let id = trigger.dataset.target;
212
- if (!id) {
213
- id = trigger.getAttribute("href");
214
- return id ? id.slice(1) : "";
215
- }
216
- return id;
212
+ return trigger.dataset.target || (trigger.getAttribute("href")?.slice(1) ?? "");
217
213
  }
218
214
  /**
219
215
  * Retrieves document scroll postion from top.
@@ -279,12 +275,11 @@ var _Utils = class _Utils {
279
275
  * Renders a button with optional callback function
280
276
  */
281
277
  static createButton(container, text, className = [], visibility = true, callback = null) {
282
- className = className.concat(["text"]);
283
278
  const button = document.createElement("button");
284
- button.className = className.join(" ");
279
+ button.className = className.concat(["text"]).join(" ");
285
280
  button.style.visibility = visibility ? "visible" : "hidden";
286
281
  button.type = "button";
287
- button.tabIndex = !!visibility ? 0 : -1;
282
+ button.tabIndex = visibility ? 0 : -1;
288
283
  button.innerText = text;
289
284
  if (typeof callback === "function") button.addEventListener("click", callback);
290
285
  container.append(button);
@@ -397,10 +392,7 @@ var Component = class {
397
392
  if (!(el instanceof HTMLElement)) {
398
393
  console.error(Error(el + " is not an HTML Element"));
399
394
  }
400
- const ins = classDef.getInstance(el);
401
- if (!!ins) {
402
- ins.destroy();
403
- }
395
+ classDef.getInstance(el)?.destroy();
404
396
  this.el = el;
405
397
  }
406
398
  /**
@@ -410,16 +402,8 @@ var Component = class {
410
402
  * @param classDef Class definition.
411
403
  */
412
404
  static init(els, options, classDef) {
413
- let instances = null;
414
- if (els instanceof Element) {
415
- instances = new classDef(els, options);
416
- } else if (els) {
417
- instances = [];
418
- for (let i = 0; i < els.length; i++) {
419
- instances.push(new classDef(els[i], options));
420
- }
421
- }
422
- return instances;
405
+ if (els instanceof Element) return new classDef(els, options);
406
+ return els ? Array.from(els, (el) => new classDef(el, options)) : null;
423
407
  }
424
408
  /**
425
409
  * @returns default options for component instance.
@@ -607,7 +591,7 @@ var Cards = class _Cards extends Component {
607
591
  Utils.onDocumentReady(() => {
608
592
  const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);
609
593
  cards.forEach((el) => {
610
- if (el && el["Expressive_Cards"] == void 0) this.init(el);
594
+ if (el["Expressive_Cards"] == void 0) this.init(el);
611
595
  });
612
596
  });
613
597
  }
@@ -650,11 +634,7 @@ var ExpandingCard = class _ExpandingCard extends Component {
650
634
  };
651
635
  this._handleNativeClose = () => {
652
636
  if (this.dialog.open) return;
653
- this.closeGeneration++;
654
- this.isOpen = false;
655
- this.trigger.ariaExpanded = "false";
656
- this.dialog.ariaExpanded = "false";
657
- this.dialog.classList.remove("expanded");
637
+ this._collapse();
658
638
  };
659
639
  this._setTransitionOrigin = () => {
660
640
  if (!this.dialog) return;
@@ -663,26 +643,15 @@ var ExpandingCard = class _ExpandingCard extends Component {
663
643
  ":scope > figure, :scope > img"
664
644
  );
665
645
  const mediaRect = media?.getBoundingClientRect();
666
- this.dialog.style.setProperty(
667
- "--md-comp-expanding-card-from-top",
668
- `${Math.max(0, card.top)}px`
669
- );
670
- this.dialog.style.setProperty(
671
- "--md-comp-expanding-card-from-right",
672
- `${Math.max(0, window.innerWidth - card.right)}px`
673
- );
674
- this.dialog.style.setProperty(
675
- "--md-comp-expanding-card-from-bottom",
676
- `${Math.max(0, window.innerHeight - card.bottom)}px`
677
- );
678
- this.dialog.style.setProperty(
679
- "--md-comp-expanding-card-from-left",
680
- `${Math.max(0, card.left)}px`
681
- );
682
- this.dialog.style.setProperty(
683
- "--md-comp-expanding-card-from-media-height",
684
- `${Math.max(0, mediaRect?.height ?? 0)}px`
646
+ const set = (side, px) => this.dialog.style.setProperty(
647
+ `--md-comp-expanding-card-from-${side}`,
648
+ `${Math.max(0, px)}px`
685
649
  );
650
+ set("top", card.top);
651
+ set("right", window.innerWidth - card.right);
652
+ set("bottom", window.innerHeight - card.bottom);
653
+ set("left", card.left);
654
+ set("media-height", mediaRect?.height ?? 0);
686
655
  };
687
656
  this.open = () => {
688
657
  if (this.isOpen || !this.dialog || !this.trigger) return;
@@ -701,12 +670,9 @@ var ExpandingCard = class _ExpandingCard extends Component {
701
670
  };
702
671
  this.close = () => {
703
672
  if (!this.isOpen || !this.dialog || !this.trigger) return;
704
- const generation = ++this.closeGeneration;
705
673
  this._setTransitionOrigin();
706
- this.isOpen = false;
707
- this.trigger.ariaExpanded = "false";
708
- this.dialog.ariaExpanded = "false";
709
- this.dialog.classList.remove("expanded");
674
+ this._collapse();
675
+ const generation = this.closeGeneration;
710
676
  if (typeof this.options.onClose === "function") {
711
677
  this.options.onClose.call(this, this.el);
712
678
  }
@@ -757,18 +723,24 @@ var ExpandingCard = class _ExpandingCard extends Component {
757
723
  }
758
724
  destroy() {
759
725
  this._removeEventHandlers();
726
+ this._collapse();
727
+ if (this.dialog?.open) this.dialog.close();
728
+ this.el["Expressive_ExpandingCard"] = void 0;
729
+ }
730
+ /** Marks the card closed and invalidates any pending close. */
731
+ _collapse() {
760
732
  this.closeGeneration++;
761
733
  this.isOpen = false;
762
734
  if (this.trigger) this.trigger.ariaExpanded = "false";
763
- if (this.dialog) this.dialog.ariaExpanded = "false";
764
- this.dialog?.classList.remove("expanded");
765
- if (this.dialog?.open) this.dialog.close();
766
- this.el["Expressive_ExpandingCard"] = void 0;
735
+ if (this.dialog) {
736
+ this.dialog.ariaExpanded = "false";
737
+ this.dialog.classList.remove("expanded");
738
+ }
767
739
  }
768
740
  static Init() {
769
741
  Utils.onDocumentReady(() => {
770
742
  document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
771
- if (el && el["Expressive_ExpandingCard"] == void 0) {
743
+ if (el["Expressive_ExpandingCard"] == void 0) {
772
744
  this.init(el);
773
745
  }
774
746
  });
@@ -854,15 +826,8 @@ var _Menu = class _Menu extends Component {
854
826
  this.close();
855
827
  return;
856
828
  }
857
- const leaveToMenuContent = !!(this.menuEl && toEl && this.menuEl.contains(toEl));
858
- let leaveToActiveMenuTrigger = false;
859
- const closestTrigger = toEl.closest(".menu-trigger");
860
- if (closestTrigger && !!closestTrigger["Expressive_Menu"] && closestTrigger["Expressive_Menu"].isOpen) {
861
- leaveToActiveMenuTrigger = true;
862
- }
863
- if (!leaveToActiveMenuTrigger && !leaveToMenuContent) {
864
- this.close();
865
- }
829
+ const leaveToActiveMenuTrigger = toEl.closest(".menu-trigger")?.["Expressive_Menu"]?.isOpen;
830
+ if (!leaveToActiveMenuTrigger && !this.menuEl?.contains(toEl)) this.close();
866
831
  };
867
832
  this._handleDocumentClick = (e) => {
868
833
  const path = e.composedPath();
@@ -874,11 +839,7 @@ var _Menu = class _Menu extends Component {
874
839
  if (this.options.closeOnClick && inside && !this.isTouchMoving) {
875
840
  this.close();
876
841
  } else if (!inside) {
877
- this._schedule(() => {
878
- if (this.isOpen) {
879
- this.close();
880
- }
881
- }, 0);
842
+ this._schedule(() => this.close(), 0);
882
843
  }
883
844
  this.isTouchMoving = false;
884
845
  };
@@ -954,11 +915,10 @@ var _Menu = class _Menu extends Component {
954
915
  if (submenu) {
955
916
  e.preventDefault();
956
917
  const parentLi = submenu.parentElement;
957
- parentLi.classList.remove("open", "submenu-start");
958
- this._syncSubmenuAria(parentLi, false);
918
+ this._closeSubmenu(parentLi);
959
919
  this._focusRow(parentLi);
960
920
  }
961
- } else if (arrowUpOrDown && this.isOpen) {
921
+ } else if (arrowUpOrDown) {
962
922
  e.preventDefault();
963
923
  const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;
964
924
  const row = this._focusedRow(e);
@@ -977,7 +937,7 @@ var _Menu = class _Menu extends Component {
977
937
  item.classList.add("active");
978
938
  this._focusRow(item);
979
939
  }
980
- } else if ((e.key === Utils.keys.ENTER || e.key === SPACE) && this.isOpen) {
940
+ } else if (e.key === Utils.keys.ENTER || e.key === SPACE) {
981
941
  const li = this._focusedRow(e);
982
942
  e.preventDefault();
983
943
  if (li?.matches('.disabled, [aria-disabled="true"]')) return;
@@ -992,19 +952,18 @@ var _Menu = class _Menu extends Component {
992
952
  } else if (focusedElement instanceof HTMLElement) {
993
953
  focusedElement.click();
994
954
  }
995
- } else if (e.key === Utils.keys.ESC && this.isOpen) {
955
+ } else if (e.key === Utils.keys.ESC) {
996
956
  e.preventDefault();
997
957
  const openSub = this._containingSubmenu(e)?.parentElement ?? Array.from(this.menuEl.querySelectorAll("li.open")).reverse()[0];
998
958
  if (openSub) {
999
- openSub.classList.remove("open", "submenu-start");
1000
- this._syncSubmenuAria(openSub, false);
959
+ this._closeSubmenu(openSub);
1001
960
  this._focusRow(openSub);
1002
961
  } else {
1003
962
  this.close();
1004
963
  }
1005
964
  }
1006
965
  const keyText = e.key.toLowerCase();
1007
- if (e.key.length === 1 && e.key !== SPACE && !e.ctrlKey && !e.metaKey && !e.altKey && !e.isComposing) {
966
+ if (e.key.length === 1 && e.key !== SPACE) {
1008
967
  this.filterQuery.push(keyText);
1009
968
  const string = this.filterQuery.join("");
1010
969
  const newOptionEl = Array.from(list.querySelectorAll(":scope > li")).find(
@@ -1229,10 +1188,7 @@ var _Menu = class _Menu extends Component {
1229
1188
  _toggleSubmenu(li) {
1230
1189
  const open = !li.classList.contains("open");
1231
1190
  li.parentElement?.querySelectorAll(":scope > li.open").forEach((other) => {
1232
- if (other !== li) {
1233
- other.classList.remove("open", "submenu-start");
1234
- this._syncSubmenuAria(other, false);
1235
- }
1191
+ if (other !== li) this._closeSubmenu(other);
1236
1192
  });
1237
1193
  li.classList.toggle("open", open);
1238
1194
  if (open) this._alignSubmenu(li);
@@ -1249,11 +1205,12 @@ var _Menu = class _Menu extends Component {
1249
1205
  const rect = menu.getBoundingClientRect();
1250
1206
  if (rect.left < 8 || rect.right > window.innerWidth - 8) li.classList.add("submenu-start");
1251
1207
  }
1208
+ _closeSubmenu(li) {
1209
+ li.classList.remove("open", "submenu-start");
1210
+ this._syncSubmenuAria(li, false);
1211
+ }
1252
1212
  _closeSubmenus() {
1253
- this.menuEl?.querySelectorAll("li.open").forEach((li) => {
1254
- li.classList.remove("open", "submenu-start");
1255
- this._syncSubmenuAria(li, false);
1256
- });
1213
+ this.menuEl?.querySelectorAll("li.open").forEach((li) => this._closeSubmenu(li));
1257
1214
  }
1258
1215
  _containingSubmenu(e) {
1259
1216
  const target = e.target;
@@ -1564,13 +1521,11 @@ var _defaults4 = {
1564
1521
  isMultiSelect: false,
1565
1522
  onSearch: (text, autocomplete) => {
1566
1523
  const normSearch = text.toLocaleLowerCase();
1567
- const data = autocomplete.options.data;
1568
1524
  autocomplete.setMenuItems(
1569
- data.filter(
1525
+ autocomplete.options.data.filter(
1570
1526
  (option) => option.id.toString().toLocaleLowerCase().includes(normSearch) || option.text?.toLocaleLowerCase().includes(normSearch)
1571
1527
  )
1572
1528
  );
1573
- autocomplete.options.data = data;
1574
1529
  },
1575
1530
  maxMenuHeight: "300px",
1576
1531
  allowUnsafeHTML: false,
@@ -1603,17 +1558,13 @@ var _Autocomplete = class _Autocomplete extends Component {
1603
1558
  this._inputChangeDetection(actualValue);
1604
1559
  };
1605
1560
  this._inputChangeDetection = (value) => {
1606
- if (!this.options.isMultiSelect && this.selectedValues.length && this.el.value !== (this.selectedValues[0].text || String(this.selectedValues[0].id))) {
1607
- this.selectedValues = [];
1608
- }
1561
+ const deselected = !this.options.isMultiSelect && this.selectedValues.length > 0 && this.el.value !== (this.selectedValues[0].text || String(this.selectedValues[0].id));
1562
+ if (deselected) this.selectedValues = [];
1609
1563
  if (this.oldVal !== value) {
1610
1564
  this._setStatusLoading();
1611
1565
  this.options.onSearch(this.el.value, this);
1612
1566
  }
1613
- if (!this.options.isMultiSelect && this.el.value.length === 0) {
1614
- this.selectedValues = [];
1615
- this._triggerChanged();
1616
- }
1567
+ if (deselected) this._triggerChanged();
1617
1568
  this.oldVal = value;
1618
1569
  };
1619
1570
  this._handleInputKeydown = (e) => {
@@ -1634,6 +1585,10 @@ var _Autocomplete = class _Autocomplete extends Component {
1634
1585
  }
1635
1586
  if (e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN) {
1636
1587
  e.preventDefault();
1588
+ if (!this.menu.isOpen && this._openTimer === void 0) {
1589
+ this.open();
1590
+ return;
1591
+ }
1637
1592
  if (e.key === Utils.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;
1638
1593
  if (e.key === Utils.keys.ARROW_DOWN && this.activeIndex < numItems - 1)
1639
1594
  this.activeIndex++;
@@ -1671,7 +1626,7 @@ var _Autocomplete = class _Autocomplete extends Component {
1671
1626
  this._resetAutocomplete();
1672
1627
  if (inputText.length >= this.options.minLength) {
1673
1628
  this._renderMenu();
1674
- this._announce(this.menuItems.length ? this.options.i18n.results(this.menuItems.length) : this.options.i18n.noResults);
1629
+ this._announce(this._resultsMessage(this.menuItems.length));
1675
1630
  }
1676
1631
  if (!this.menu.isOpen) {
1677
1632
  if (this._openTimer !== void 0) clearTimeout(this._openTimer);
@@ -1833,6 +1788,7 @@ var _Autocomplete = class _Autocomplete extends Component {
1833
1788
  const label = this.el.parentElement.querySelector("label");
1834
1789
  if (label) this.el.after(label);
1835
1790
  this.el.removeEventListener("click", this.menu._handleClick);
1791
+ this.el.removeEventListener("keydown", this.menu._handleTriggerKeydown);
1836
1792
  if (!this.options.isMultiSelect) this._refreshInputText();
1837
1793
  if (this.el.value) this.selectOption(this.el.value);
1838
1794
  const div = document.createElement("div");
@@ -1864,7 +1820,7 @@ var _Autocomplete = class _Autocomplete extends Component {
1864
1820
  this._pointerDown = false;
1865
1821
  }
1866
1822
  _highlightPartialText(input, label) {
1867
- const start = label.toLocaleLowerCase().indexOf("" + input.toLocaleLowerCase());
1823
+ const start = label.toLocaleLowerCase().indexOf(input.toLocaleLowerCase());
1868
1824
  const end = start + input.length - 1;
1869
1825
  if (start == -1 || end == -1) {
1870
1826
  return [label, "", ""];
@@ -1935,7 +1891,7 @@ var _Autocomplete = class _Autocomplete extends Component {
1935
1891
  itemText.classList.add("item-text");
1936
1892
  itemText.setAttribute("style", "padding:5px;overflow:hidden;");
1937
1893
  item.appendChild(itemText);
1938
- item.querySelector(".item-text").appendChild(div);
1894
+ itemText.appendChild(div);
1939
1895
  if (typeof entry.description === "string" || typeof entry.description === "number" && !isNaN(entry.description)) {
1940
1896
  const description = document.createElement("small");
1941
1897
  description.setAttribute(
@@ -1943,7 +1899,7 @@ var _Autocomplete = class _Autocomplete extends Component {
1943
1899
  "line-height:1.3;color:grey;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden;"
1944
1900
  );
1945
1901
  description.innerText = entry.description;
1946
- item.querySelector(".item-text").appendChild(description);
1902
+ itemText.appendChild(description);
1947
1903
  }
1948
1904
  const getGridConfig = () => {
1949
1905
  if (this.options.isMultiSelect) {
@@ -1976,6 +1932,9 @@ var _Autocomplete = class _Autocomplete extends Component {
1976
1932
  const text = this.el.matches(":focus") && this.el.value.length >= this.options.minLength ? message : "";
1977
1933
  if (this._announcer.textContent !== text) this._announcer.textContent = text;
1978
1934
  }
1935
+ _resultsMessage(count) {
1936
+ return count ? this.options.i18n.results(count) : this.options.i18n.noResults;
1937
+ }
1979
1938
  _updateSelectedInfo() {
1980
1939
  const statusElement = this._statusInfo;
1981
1940
  if (statusElement) {
@@ -2005,7 +1964,6 @@ var _Autocomplete = class _Autocomplete extends Component {
2005
1964
  if (this.el["Expressive_Autocomplete"] !== this) return;
2006
1965
  const resultCount = menuItems.length;
2007
1966
  this.menuItems = menuItems;
2008
- this.options.data = menuItems;
2009
1967
  if (selected) {
2010
1968
  this.selectedValues = this.menuItems.filter(
2011
1969
  (item) => !(selected.indexOf(item.id) === -1)
@@ -2018,8 +1976,8 @@ var _Autocomplete = class _Autocomplete extends Component {
2018
1976
  }
2019
1977
  if (open) this.open();
2020
1978
  this._updateSelectedInfo();
2021
- this._announce(open ? resultCount ? this.options.i18n.results(resultCount) : this.options.i18n.noResults : "");
2022
- this._triggerChanged();
1979
+ this._announce(open ? this._resultsMessage(resultCount) : "");
1980
+ if (selected) this._triggerChanged();
2023
1981
  }
2024
1982
  /**
2025
1983
  * Select a specific autocomplete option via id-property.
@@ -2029,9 +1987,8 @@ var _Autocomplete = class _Autocomplete extends Component {
2029
1987
  const entry = this.menuItems.find((item) => item.id == id);
2030
1988
  if (!entry) return;
2031
1989
  if (this.options.isMultiSelect) {
2032
- if (!(this.selectedValues.filter(
2033
- (selectedEntry) => selectedEntry.id === entry.id
2034
- ).length >= 1)) this.selectedValues.push(entry);
1990
+ if (!this.selectedValues.some((selectedEntry) => selectedEntry.id === entry.id))
1991
+ this.selectedValues.push(entry);
2035
1992
  else this.selectedValues = this.selectedValues.filter(
2036
1993
  (selectedEntry) => selectedEntry.id !== entry.id
2037
1994
  );
@@ -2104,7 +2061,7 @@ var _Chips = class _Chips extends Component {
2104
2061
  return;
2105
2062
  }
2106
2063
  e.preventDefault();
2107
- if (!this.hasAutocomplete || this.hasAutocomplete && !this.options.autocompleteOnly) {
2064
+ if (!this.hasAutocomplete || !this.options.autocompleteOnly) {
2108
2065
  this.addChip({ id: this._input.value });
2109
2066
  }
2110
2067
  this._input.value = "";
@@ -2197,9 +2154,8 @@ var _Chips = class _Chips extends Component {
2197
2154
  static _handleChipsKeydown(e) {
2198
2155
  _Chips._keydown = true;
2199
2156
  const chips = e.target.closest(".chips");
2200
- const chipsKeydown = e.target && chips;
2201
2157
  const tag = e.target.tagName;
2202
- if (tag === "INPUT" || tag === "TEXTAREA" || !chipsKeydown) return;
2158
+ if (tag === "INPUT" || tag === "TEXTAREA" || !chips) return;
2203
2159
  const currChips = chips["Expressive_Chips"];
2204
2160
  if (!currChips) return;
2205
2161
  if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {
@@ -2299,9 +2255,9 @@ var _Chips = class _Chips extends Component {
2299
2255
  }
2300
2256
  _setPlaceholder() {
2301
2257
  if (!this._input) return;
2302
- if (this.chipsData !== void 0 && !this.chipsData.length && this.options.placeholder) {
2258
+ if (!this.chipsData.length && this.options.placeholder) {
2303
2259
  this._input.placeholder = this.options.placeholder;
2304
- } else if ((this.chipsData === void 0 || !!this.chipsData.length) && this.options.secondaryPlaceholder) {
2260
+ } else if (this.chipsData.length && this.options.secondaryPlaceholder) {
2305
2261
  this._input.placeholder = this.options.secondaryPlaceholder;
2306
2262
  }
2307
2263
  }
@@ -2518,10 +2474,13 @@ var Slider = class _Slider extends Component {
2518
2474
  if (this.el === start && +start.value > +end.value) start.value = end.value;
2519
2475
  if (this.el === end && +end.value < +start.value) end.value = start.value;
2520
2476
  }
2521
- _fraction(el) {
2477
+ /** The input's range, defaulting like the browser does: 0 to 100. */
2478
+ _bounds(el) {
2522
2479
  const parsedMax = parseFloat(el.max);
2523
- const max = Number.isNaN(parsedMax) ? 100 : parsedMax;
2524
- const min = parseFloat(el.min) || 0;
2480
+ return { max: Number.isNaN(parsedMax) ? 100 : parsedMax, min: parseFloat(el.min) || 0 };
2481
+ }
2482
+ _fraction(el) {
2483
+ const { max, min } = this._bounds(el);
2525
2484
  const val = parseFloat(el.value) || 0;
2526
2485
  return max === min ? 0 : (val - min) / (max - min);
2527
2486
  }
@@ -2550,9 +2509,7 @@ var Slider = class _Slider extends Component {
2550
2509
  this._set(host, "--md-comp-slider-end-position", `${handle / 2 + Math.max(...nums) * (length - handle)}px`);
2551
2510
  }
2552
2511
  if (host?.classList.contains("stops")) {
2553
- const parsedMax = parseFloat(this.el.max);
2554
- const max = Number.isNaN(parsedMax) ? 100 : parsedMax;
2555
- const min = parseFloat(this.el.min) || 0;
2512
+ const { max, min } = this._bounds(this.el);
2556
2513
  const step = parseFloat(this.el.step);
2557
2514
  const stops = step > 0 && Number.isFinite(step) && max > min;
2558
2515
  this._set(host, "--md-comp-slider-stop-count", stops ? String(Math.floor((max - min) / step + 1e-9) + 1) : "");
@@ -2576,7 +2533,7 @@ var Slider = class _Slider extends Component {
2576
2533
  */
2577
2534
  static Init() {
2578
2535
  Utils.onDocumentReady(() => {
2579
- _Slider.init(document.querySelectorAll("input[type=range]"), {});
2536
+ _Slider.init(document.querySelectorAll("input[type=range]"));
2580
2537
  });
2581
2538
  }
2582
2539
  };
@@ -2591,16 +2548,8 @@ var _Dialogs = class _Dialogs {
2591
2548
  });
2592
2549
  }
2593
2550
  static _onPointerDown(event) {
2594
- if (!_Dialogs._isPrimaryPress(event)) {
2595
- _Dialogs._down = null;
2596
- return;
2597
- }
2598
- const dialog = _Dialogs._backdropDialog(event);
2599
- if (!dialog || !_Dialogs._lightDismissible(dialog) || !_Dialogs._outside(event, dialog)) {
2600
- _Dialogs._down = null;
2601
- return;
2602
- }
2603
- _Dialogs._down = { dialog, pointerId: event.pointerId };
2551
+ const dialog = _Dialogs._isPrimaryPress(event) ? _Dialogs._backdropDialog(event) : null;
2552
+ _Dialogs._down = dialog && _Dialogs._lightDismissible(dialog) && _Dialogs._outside(event, dialog) ? { dialog, pointerId: event.pointerId } : null;
2604
2553
  }
2605
2554
  static _onPointerUp(event) {
2606
2555
  const started = _Dialogs._down;
@@ -2676,21 +2625,15 @@ function installSheetDrag(config) {
2676
2625
  onCancel();
2677
2626
  config.onPress?.();
2678
2627
  const dialog = sheetFor(event.target);
2679
- if (!dialog?.open) {
2680
- drag = null;
2681
- return;
2682
- }
2683
- if (!config.inHandle(event, dialog)) {
2684
- drag = null;
2685
- return;
2686
- }
2628
+ if (!dialog?.open || !config.inHandle(event, dialog)) return;
2687
2629
  dialog.style.transition = "none";
2630
+ const at = coord(event);
2688
2631
  drag = {
2689
2632
  dialog,
2690
2633
  pointerId: event.pointerId,
2691
2634
  direction: config.direction(dialog),
2692
- start: coord(event),
2693
- last: coord(event),
2635
+ start: at,
2636
+ last: at,
2694
2637
  lastT: Date.now(),
2695
2638
  velocity: 0,
2696
2639
  shift: 0
@@ -2703,12 +2646,13 @@ function installSheetDrag(config) {
2703
2646
  onCancel();
2704
2647
  return;
2705
2648
  }
2706
- const delta = coord(event) - drag.start;
2649
+ const at = coord(event);
2650
+ const delta = at - drag.start;
2707
2651
  drag.shift = drag.direction === 1 ? Math.max(0, delta) : Math.min(0, delta);
2708
- if (coord(event) !== drag.last) {
2652
+ if (at !== drag.last) {
2709
2653
  const now = Date.now();
2710
- drag.velocity = (coord(event) - drag.last) / Math.max(1, now - drag.lastT);
2711
- drag.last = coord(event);
2654
+ drag.velocity = (at - drag.last) / Math.max(1, now - drag.lastT);
2655
+ drag.last = at;
2712
2656
  drag.lastT = now;
2713
2657
  }
2714
2658
  drag.dialog.style.setProperty(config.property, `${drag.shift}px`);
@@ -2835,7 +2779,7 @@ var _Forms = class _Forms {
2835
2779
  if (len === 0 && textfield.validity.badInput === false && !textfield.required && textfield.classList.contains("validate")) {
2836
2780
  textfield.classList.remove("invalid");
2837
2781
  } else if (textfield.classList.contains("validate")) {
2838
- if (textfield.validity.valid && hasLength && len <= lenAttr || textfield.validity.valid && !hasLength) {
2782
+ if (textfield.validity.valid && (!hasLength || len <= lenAttr)) {
2839
2783
  textfield.classList.remove("invalid");
2840
2784
  } else {
2841
2785
  textfield.classList.add("invalid");
@@ -2870,13 +2814,12 @@ var _Forms = class _Forms {
2870
2814
  Utils.onDocumentReady(() => {
2871
2815
  document.addEventListener("change", (e) => {
2872
2816
  const target = e.target;
2873
- if (target instanceof HTMLInputElement && target.type === "file") {
2817
+ if (!(target instanceof HTMLInputElement)) return;
2818
+ if (target.type === "file") {
2874
2819
  const zone = target.closest(".drop-zone");
2875
2820
  if (zone) _Forms.listDropZoneFiles(zone, target);
2876
2821
  }
2877
- if (target instanceof HTMLInputElement) {
2878
- _Forms.validateField(target);
2879
- }
2822
+ _Forms.validateField(target);
2880
2823
  });
2881
2824
  document.addEventListener("keyup", (e) => {
2882
2825
  const target = e.target;
@@ -2981,12 +2924,7 @@ var _Forms = class _Forms {
2981
2924
  fileInput.addEventListener("change", () => {
2982
2925
  const fileField = fileInput.closest(".file-field");
2983
2926
  const pathInput = fileField.querySelector("input.file-path");
2984
- const files = fileInput.files;
2985
- const filenames = [];
2986
- for (let i = 0; i < files.length; i++) {
2987
- filenames.push(files[i].name);
2988
- }
2989
- pathInput.value = filenames.join(", ");
2927
+ pathInput.value = Array.from(fileInput.files, (f) => f.name).join(", ");
2990
2928
  pathInput.dispatchEvent(
2991
2929
  new Event("change", { bubbles: true, cancelable: true, composed: true })
2992
2930
  );
@@ -3068,8 +3006,7 @@ var AppBar = class _AppBar extends Component {
3068
3006
  this._input = this.el.querySelector('input[type="search"]');
3069
3007
  if (!this._input) return;
3070
3008
  const id = this._input.getAttribute("aria-controls");
3071
- if (id) this._view = document.getElementById(id);
3072
- if (!this._view) this._view = this.el.querySelector(".search-view");
3009
+ this._view = id && document.getElementById(id) || this.el.querySelector(".search-view");
3073
3010
  if (!this._view) return;
3074
3011
  this._input.addEventListener("focus", this._onSearchFocus);
3075
3012
  this._input.addEventListener("click", this._onSearchFocus);
@@ -3397,6 +3334,7 @@ var _defaults10 = {
3397
3334
  slide: "Slide"
3398
3335
  }
3399
3336
  };
3337
+ var naturallyFocusable = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
3400
3338
  var _Carousel = class _Carousel extends Component {
3401
3339
  constructor(el, options) {
3402
3340
  super(el, options, _Carousel);
@@ -3698,7 +3636,6 @@ var _Carousel = class _Carousel extends Component {
3698
3636
  this.el.setAttribute("aria-roledescription", "carousel");
3699
3637
  this._generatedContainerDescription = true;
3700
3638
  }
3701
- const naturallyFocusable = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
3702
3639
  this.images.forEach((item, index) => {
3703
3640
  if (!item.hasAttribute("aria-roledescription")) {
3704
3641
  item.setAttribute("aria-roledescription", "slide");
@@ -3731,10 +3668,6 @@ var _Carousel = class _Carousel extends Component {
3731
3668
  const button = document.createElement("button");
3732
3669
  button.type = "button";
3733
3670
  button.classList.add("indicator-item");
3734
- if (i === 0) {
3735
- button.classList.add("active");
3736
- button.setAttribute("aria-current", "true");
3737
- }
3738
3671
  button.setAttribute("aria-label", `${this.options.i18n.slide} ${i + 1}`);
3739
3672
  this._indicators.appendChild(button);
3740
3673
  });
@@ -3932,11 +3865,7 @@ var _Carousel = class _Carousel extends Component {
3932
3865
  _focusItem(index) {
3933
3866
  const item = this.images[index];
3934
3867
  if (!item) return;
3935
- const focusable = item.matches(
3936
- 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
3937
- ) ? item : item.querySelector(
3938
- 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
3939
- );
3868
+ const focusable = item.matches(naturallyFocusable) ? item : item.querySelector(naturallyFocusable);
3940
3869
  (focusable ?? item).focus({ preventScroll: true });
3941
3870
  }
3942
3871
  _updateParallax() {
@@ -4033,13 +3962,13 @@ var _Carousel = class _Carousel extends Component {
4033
3962
  this._syncAutoAdvance();
4034
3963
  }
4035
3964
  next(n = 1) {
4036
- if (n === void 0 || isNaN(n)) n = 1;
3965
+ if (isNaN(n)) n = 1;
4037
3966
  const index = this.center + n;
4038
3967
  if (index >= this.count || index < 0) return;
4039
3968
  this._cycleTo(index);
4040
3969
  }
4041
3970
  prev(n = 1) {
4042
- if (n === void 0 || isNaN(n)) n = 1;
3971
+ if (isNaN(n)) n = 1;
4043
3972
  const index = this.center - n;
4044
3973
  if (index >= this.count || index < 0) return;
4045
3974
  this._cycleTo(index);
@@ -4486,8 +4415,132 @@ var Particles = class _Particles extends Component {
4486
4415
  }
4487
4416
  };
4488
4417
 
4489
- // src/ts/components/commandPalette.ts
4418
+ // src/ts/components/keypad.ts
4490
4419
  var _defaults14 = {
4420
+ onKey: null
4421
+ };
4422
+ var isField = (el) => el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement;
4423
+ var instances = /* @__PURE__ */ new Set();
4424
+ var touched = /* @__PURE__ */ new WeakSet();
4425
+ var segmenter;
4426
+ function keyFor(e) {
4427
+ const key = e.target.closest?.("button");
4428
+ if (!key) return null;
4429
+ const keypad = key.closest(".keypad, .keyboard")?.["Expressive_Keypad"];
4430
+ if (keypad) return [keypad, key];
4431
+ const wrapper = key.dataset.key && key.closest(".field");
4432
+ if (!wrapper) return null;
4433
+ for (const other of instances) {
4434
+ const field = other.target;
4435
+ if (field && wrapper.contains(field)) return [other, key];
4436
+ }
4437
+ return null;
4438
+ }
4439
+ var rootListeners = [
4440
+ // A pointer press on a key would move focus off the field and hide its
4441
+ // caret. Keep focus where it is while the field has it.
4442
+ ["mousedown", (e) => {
4443
+ const hit = keyFor(e);
4444
+ if (hit && hit[0]._root?.activeElement === hit[0].target) e.preventDefault();
4445
+ }],
4446
+ ["click", (e) => {
4447
+ const hit = keyFor(e);
4448
+ if (hit) hit[0]._press(hit[1]);
4449
+ }],
4450
+ ["focusin", (e) => {
4451
+ if (isField(e.target)) touched.add(e.target);
4452
+ }]
4453
+ ];
4454
+ var Keypad = class _Keypad extends Component {
4455
+ constructor(el, options) {
4456
+ super(el, options, _Keypad);
4457
+ this.el["Expressive_Keypad"] = this;
4458
+ this.options = { ..._Keypad.defaults, ...options };
4459
+ const root = this.el.getRootNode();
4460
+ this._root = root.nodeType === 9 || root.nodeType === 11 ? root : null;
4461
+ if (this._root && !this._shared()) {
4462
+ for (const [type, listener] of rootListeners) this._root.addEventListener(type, listener);
4463
+ }
4464
+ instances.add(this);
4465
+ const active = this._root?.activeElement;
4466
+ if (isField(active)) touched.add(active);
4467
+ }
4468
+ static get defaults() {
4469
+ return _defaults14;
4470
+ }
4471
+ static init(els, options = {}) {
4472
+ return super.init(els, options, _Keypad);
4473
+ }
4474
+ static getInstance(el) {
4475
+ return el["Expressive_Keypad"];
4476
+ }
4477
+ destroy() {
4478
+ instances.delete(this);
4479
+ if (this._root && !this._shared()) {
4480
+ for (const [type, listener] of rootListeners) this._root.removeEventListener(type, listener);
4481
+ }
4482
+ this.el["Expressive_Keypad"] = void 0;
4483
+ }
4484
+ /** The text field named by `aria-controls`, if there is one. */
4485
+ get target() {
4486
+ const id = this.el.getAttribute("aria-controls");
4487
+ const field = id ? Utils.getElementById(this.el, id) : null;
4488
+ return isField(field) ? field : null;
4489
+ }
4490
+ // Whether another keypad already listens on this one's root.
4491
+ _shared() {
4492
+ for (const other of instances) if (other !== this && other._root === this._root) return true;
4493
+ return false;
4494
+ }
4495
+ /** @internal */
4496
+ _press(key) {
4497
+ const name = key.dataset.key;
4498
+ if (key.disabled || !name && !key.hasAttribute("value")) return;
4499
+ if (name === "Shift") {
4500
+ key.setAttribute("aria-pressed", String(key.getAttribute("aria-pressed") !== "true"));
4501
+ this.options.onKey?.(name);
4502
+ return;
4503
+ }
4504
+ let text = name ? "" : key.value;
4505
+ const shift = text && this.el.querySelector('[data-key="Shift"][aria-pressed="true"]');
4506
+ if (shift) {
4507
+ text = text.toUpperCase();
4508
+ shift.setAttribute("aria-pressed", "false");
4509
+ }
4510
+ const field = this.target;
4511
+ if (field && !field.matches(":disabled") && !field.readOnly) {
4512
+ if (name === "Enter" && field instanceof HTMLInputElement) field.form?.requestSubmit();
4513
+ else if (name === "Enter") this._edit(field, "\n", "insertLineBreak");
4514
+ else if (name === "Backspace") this._edit(field, "", "deleteContentBackward");
4515
+ else if (text) this._edit(field, text, "insertText");
4516
+ }
4517
+ this.options.onKey?.(name ?? text);
4518
+ }
4519
+ _edit(field, text, inputType) {
4520
+ const { value } = field;
4521
+ let start = field.selectionStart ?? value.length;
4522
+ let end = field.selectionEnd ?? value.length;
4523
+ if (start === 0 && end === 0 && !touched.has(field)) start = end = value.length;
4524
+ if (inputType === "deleteContentBackward" && start === end && start) {
4525
+ const tail = value.slice(Math.max(0, start - 64), start);
4526
+ start -= (segmenter ?? (segmenter = new Intl.Segmenter())).segment(tail).containing(tail.length - 1).segment.length;
4527
+ }
4528
+ if (start === end && !text) return;
4529
+ if (text && field.maxLength >= 0 && value.length - (end - start) + text.length > field.maxLength) return;
4530
+ const next = value.slice(0, start) + text + value.slice(end);
4531
+ field.value = next;
4532
+ if (next && !field.value) {
4533
+ field.value = value;
4534
+ return;
4535
+ }
4536
+ if (field.selectionStart !== null) field.setSelectionRange(start + text.length, start + text.length);
4537
+ touched.add(field);
4538
+ field.dispatchEvent(new InputEvent("input", { bubbles: true, composed: true, inputType, data: text || null }));
4539
+ }
4540
+ };
4541
+
4542
+ // src/ts/components/commandPalette.ts
4543
+ var _defaults15 = {
4491
4544
  shortcut: "k",
4492
4545
  closeOnRun: true
4493
4546
  };
@@ -4585,7 +4638,7 @@ var CommandPalette = class _CommandPalette extends Component {
4585
4638
  document.addEventListener("keydown", this._handleShortcut);
4586
4639
  }
4587
4640
  static get defaults() {
4588
- return _defaults14;
4641
+ return _defaults15;
4589
4642
  }
4590
4643
  /**
4591
4644
  * Initializes instances of CommandPalette.
@@ -4738,7 +4791,7 @@ var CommandPalette = class _CommandPalette extends Component {
4738
4791
  };
4739
4792
 
4740
4793
  // src/ts/components/questionnaire.ts
4741
- var _defaults15 = {
4794
+ var _defaults16 = {
4742
4795
  progressLabel: "Question {current} of {total}",
4743
4796
  requiredMessage: "Choose an answer to continue."
4744
4797
  };
@@ -4852,7 +4905,7 @@ var Questionnaire = class _Questionnaire extends Component {
4852
4905
  this.el.addEventListener("invalid", this._handleInvalid, true);
4853
4906
  }
4854
4907
  static get defaults() {
4855
- return _defaults15;
4908
+ return _defaults16;
4856
4909
  }
4857
4910
  /**
4858
4911
  * Initializes instances of Questionnaire.
@@ -4997,7 +5050,7 @@ var Questionnaire = class _Questionnaire extends Component {
4997
5050
  };
4998
5051
 
4999
5052
  // src/ts/components/lineChart.ts
5000
- var _defaults16 = {
5053
+ var _defaults17 = {
5001
5054
  min: null,
5002
5055
  max: null
5003
5056
  };
@@ -5008,13 +5061,19 @@ function svgNode(name, attributes = {}) {
5008
5061
  for (const key in attributes) element.setAttribute(key, attributes[key]);
5009
5062
  return element;
5010
5063
  }
5064
+ function polarPoint(turn, r) {
5065
+ const angle = turn * 2 * Math.PI;
5066
+ return `${(r * Math.sin(angle)).toFixed(3)},${(-r * Math.cos(angle)).toFixed(3)}`;
5067
+ }
5068
+ var seriesColor = (i) => String(i % COLORS + 1);
5011
5069
  var _gradientId = 0;
5012
5070
  function cellValue(cell) {
5013
5071
  if (!cell) return null;
5014
5072
  const raw = cell.dataset.value ?? cell.textContent;
5015
5073
  const text = raw.replace(/\u2212/g, "-").replace(/[\s%\p{Sc}]/gu, "");
5016
- if (!/^[+-]?(\d{1,3}(,\d{3})+|\d+)?(\.\d+)?(e[+-]?\d+)?$/i.test(text) || !/\d/.test(text)) return null;
5017
- return parseFloat(text.replace(/,/g, ""));
5074
+ if (!/^[+-]?(\d{1,3}(,\d{3})+|\d+)?(\.\d+)?(e[+-]?\d+)?$/i.test(text)) return null;
5075
+ const value = parseFloat(text.replace(/,/g, ""));
5076
+ return Number.isFinite(value) ? value : null;
5018
5077
  }
5019
5078
  function monotonePath(points) {
5020
5079
  const n = points.length;
@@ -5125,7 +5184,7 @@ var LineChart = class extends Component {
5125
5184
  return "Expressive_LineChart";
5126
5185
  }
5127
5186
  static get defaults() {
5128
- return _defaults16;
5187
+ return _defaults17;
5129
5188
  }
5130
5189
  static init(els, options = {}) {
5131
5190
  return super.init(els, options, this);
@@ -5155,7 +5214,7 @@ var LineChart = class extends Component {
5155
5214
  this.series.forEach((series, i) => {
5156
5215
  const value = series.values[index];
5157
5216
  if (value === null) return;
5158
- const color = String(i % COLORS + 1);
5217
+ const color = seriesColor(i);
5159
5218
  const top = series.tops[index];
5160
5219
  if (top !== null && this._points) {
5161
5220
  const dot = document.createElement("span");
@@ -5307,7 +5366,7 @@ var LineChart = class extends Component {
5307
5366
  legend.setAttribute("aria-hidden", "true");
5308
5367
  legend.append(...this.series.map((series, i) => {
5309
5368
  const li = document.createElement("li");
5310
- li.dataset.series = String(i % COLORS + 1);
5369
+ li.dataset.series = seriesColor(i);
5311
5370
  li.textContent = series.name;
5312
5371
  return li;
5313
5372
  }));
@@ -5315,15 +5374,17 @@ var LineChart = class extends Component {
5315
5374
  }
5316
5375
  /** Draws the series, which fill the plot. */
5317
5376
  _draw(drawn = this.series) {
5318
- const svg = document.createElementNS(SVG, "svg");
5319
- svg.setAttribute("viewBox", "0 0 100 100");
5320
- svg.setAttribute("preserveAspectRatio", "none");
5321
- svg.setAttribute("aria-hidden", "true");
5322
- svg.setAttribute("focusable", "false");
5377
+ const svg = svgNode("svg", {
5378
+ viewBox: "0 0 100 100",
5379
+ preserveAspectRatio: "none",
5380
+ "aria-hidden": "true",
5381
+ focusable: "false"
5382
+ });
5323
5383
  for (const series of drawn) {
5324
- const group = document.createElementNS(SVG, "g");
5325
- group.setAttribute("class", `${this._type}-series ${series.className}`.trim());
5326
- group.dataset.series = String(this.series.indexOf(series) % COLORS + 1);
5384
+ const group = svgNode("g", {
5385
+ class: `${this._type}-series ${series.className}`.trim(),
5386
+ "data-series": seriesColor(this.series.indexOf(series))
5387
+ });
5327
5388
  const runs = [[]];
5328
5389
  series.tops.forEach((value, index) => {
5329
5390
  if (value === null) runs.push([]);
@@ -5333,23 +5394,21 @@ var LineChart = class extends Component {
5333
5394
  const points = (run, values) => run.map((index) => [this._x(index), series.y(values[index])]);
5334
5395
  const tops = filled.map((run) => monotonePath(points(run, series.tops)));
5335
5396
  const id = `line-chart-gradient-${++_gradientId}`;
5336
- const gradient = document.createElementNS(SVG, "linearGradient");
5337
- gradient.id = id;
5338
- gradient.setAttribute("x2", "0");
5339
- gradient.setAttribute("y2", "1");
5340
- gradient.append(document.createElementNS(SVG, "stop"), document.createElementNS(SVG, "stop"));
5341
- gradient.lastElementChild.setAttribute("offset", "1");
5342
- const area = document.createElementNS(SVG, "path");
5343
- area.setAttribute("class", `${this._type}-area`);
5344
- area.setAttribute("fill", `url(#${id})`);
5345
- area.setAttribute("d", filled.map((run, r) => {
5346
- if (!series.base) return `${tops[r]}V100H${this._x(run[0])}Z`;
5347
- const base = points(run, series.base).map(([x, y]) => [x, Math.min(100, y)]);
5348
- return `${tops[r]}L${monotonePath(base.reverse()).slice(1)}Z`;
5349
- }).join(""));
5350
- const line = document.createElementNS(SVG, "path");
5351
- line.setAttribute("class", `${this._type}-line`);
5352
- line.setAttribute("d", tops.join(""));
5397
+ const gradient = svgNode("linearGradient", { id, x2: "0", y2: "1" });
5398
+ gradient.append(svgNode("stop"), svgNode("stop", { offset: "1" }));
5399
+ const area = svgNode("path", {
5400
+ class: `${this._type}-area`,
5401
+ fill: `url(#${id})`,
5402
+ // A stacked area runs back along the series below; the reversed curve
5403
+ // is the same curve. Its base stops at the plot bottom when the y axis
5404
+ // starts above zero.
5405
+ d: filled.map((run, r) => {
5406
+ if (!series.base) return `${tops[r]}V100H${this._x(run[0])}Z`;
5407
+ const base = points(run, series.base).map(([x, y]) => [x, Math.min(100, y)]);
5408
+ return `${tops[r]}L${monotonePath(base.reverse()).slice(1)}Z`;
5409
+ }).join("")
5410
+ });
5411
+ const line = svgNode("path", { class: `${this._type}-line`, d: tops.join("") });
5353
5412
  group.append(gradient, area, line);
5354
5413
  svg.append(group);
5355
5414
  }
@@ -5428,7 +5487,7 @@ var ColumnChart = class extends LineChart {
5428
5487
  const column = document.createElement("span");
5429
5488
  if (to !== null) {
5430
5489
  column.className = series.className;
5431
- column.dataset.series = String(this.series.indexOf(series) % COLORS + 1);
5490
+ column.dataset.series = seriesColor(this.series.indexOf(series));
5432
5491
  column.classList.toggle("negative", !series.base && to < from);
5433
5492
  column.style.setProperty("--top", `${clamp(Math.max(from, to), series.y)}%`);
5434
5493
  column.style.setProperty("--bottom", `${100 - clamp(Math.min(from, to), series.y)}%`);
@@ -5583,17 +5642,13 @@ var PieChart = class extends LineChart {
5583
5642
  const total = values.reduce((sum, value) => sum + value, 0);
5584
5643
  let turn = 0;
5585
5644
  this._turns = values.map((value) => [turn, turn += total ? value / total : 0]);
5586
- const drawn = this._turns.filter(([start, end]) => end > start).length;
5645
+ const drawn = this._turns.filter(([start, end]) => end > start);
5587
5646
  let slice = 0;
5588
5647
  this._colors = this._turns.map(([start, end]) => {
5589
5648
  if (end <= start) return void 0;
5590
5649
  const index = slice++;
5591
- return String(index === drawn - 1 && index > 0 && index % COLORS2 === 0 ? 2 : index % COLORS2 + 1);
5650
+ return String(index === drawn.length - 1 && index > 0 && index % COLORS2 === 0 ? 2 : index % COLORS2 + 1);
5592
5651
  });
5593
- const at = (t, r = RADIUS) => {
5594
- const angle = t * 2 * Math.PI;
5595
- return `${(r * Math.sin(angle)).toFixed(3)},${(-r * Math.cos(angle)).toFixed(3)}`;
5596
- };
5597
5652
  const pie = document.createElement("div");
5598
5653
  pie.className = "pie-chart-pie";
5599
5654
  pie.setAttribute("aria-hidden", "true");
@@ -5601,13 +5656,12 @@ var PieChart = class extends LineChart {
5601
5656
  const id = `pie-chart-mask-${++_maskId}`;
5602
5657
  const area = { x: "-50", y: "-50", width: "100", height: "100" };
5603
5658
  const mask = svgNode("mask", { id, maskUnits: "userSpaceOnUse", ...area });
5604
- const edges = this._turns.filter(([start, end]) => end > start);
5605
5659
  mask.append(
5606
5660
  svgNode("rect", { ...area, fill: "white" }),
5607
5661
  svgNode("path", {
5608
5662
  class: "pie-chart-gaps",
5609
5663
  stroke: "black",
5610
- d: edges.length > 1 ? edges.map(([start]) => `M0,0L${at(start, 50)}`).join("") : ""
5664
+ d: drawn.length > 1 ? drawn.map(([start]) => `M0,0L${polarPoint(start, 50)}`).join("") : ""
5611
5665
  }),
5612
5666
  svgNode("circle", { class: "pie-chart-hole", r: String(RADIUS), fill: "black" })
5613
5667
  );
@@ -5619,7 +5673,7 @@ var PieChart = class extends LineChart {
5619
5673
  class: "pie-chart-slice",
5620
5674
  "data-series": this._colors[i],
5621
5675
  // A whole circle is two half arcs; one arc cannot end where it starts.
5622
- d: end - start >= 1 ? `M0,${-RADIUS}${arc2} 1 1 0,${RADIUS}${arc2} 1 1 0,${-RADIUS}Z` : `M0,0L${at(start)}${arc2} ${end - start > 0.5 ? 1 : 0} 1 ${at(end)}Z`
5676
+ d: end - start >= 1 ? `M0,${-RADIUS}${arc2} 1 1 0,${RADIUS}${arc2} 1 1 0,${-RADIUS}Z` : `M0,0L${polarPoint(start, RADIUS)}${arc2} ${end - start > 0.5 ? 1 : 0} 1 ${polarPoint(end, RADIUS)}Z`
5623
5677
  });
5624
5678
  slices.append(slice2);
5625
5679
  return slice2;
@@ -5752,10 +5806,7 @@ var HeatmapChart = class extends LineChart {
5752
5806
  if (value < low) [low, this._ends[0]] = [value, series.text[row]];
5753
5807
  if (value > high) [high, this._ends[1]] = [value, series.text[row]];
5754
5808
  }));
5755
- const option = (name) => {
5756
- const value = parseFloat(this.el.dataset[name] ?? "");
5757
- return Number.isFinite(value) ? value : this.options[name];
5758
- };
5809
+ const option = (name) => this._number(name) ?? this.options[name];
5759
5810
  const [min, max] = [option("min") ?? low, option("max") ?? high];
5760
5811
  const shade = (value) => Math.min(1, Math.max(0, (value - min) / (max - min || 1)));
5761
5812
  this._endLevels = [shade(low), shade(high)];
@@ -5856,10 +5907,7 @@ var RadarChart = class extends LineChart {
5856
5907
  * the labels round it are HTML.
5857
5908
  */
5858
5909
  _draw() {
5859
- const at = (index, share2) => {
5860
- const angle = this._turn(index) * 2 * Math.PI;
5861
- return `${(50 * share2 * Math.sin(angle)).toFixed(3)},${(-50 * share2 * Math.cos(angle)).toFixed(3)}`;
5862
- };
5910
+ const at = (index, share2) => polarPoint(this._turn(index), 50 * share2);
5863
5911
  const share = (value) => Math.min(1, Math.max(0, 1 - this._y(value) / 100));
5864
5912
  const rows = this.labels.map((_, i) => i);
5865
5913
  const ring = (r) => `M${rows.map((i) => at(i, r)).join("L")}Z`;
@@ -5872,7 +5920,7 @@ var RadarChart = class extends LineChart {
5872
5920
  this.series.forEach((series, s) => {
5873
5921
  const group = svgNode("g", {
5874
5922
  class: `radar-chart-series ${series.className}`.trim(),
5875
- "data-series": String(s % COLORS + 1)
5923
+ "data-series": seriesColor(s)
5876
5924
  });
5877
5925
  const drawn = rows.filter((i) => series.values[i] !== null);
5878
5926
  const corners = drawn.map((i) => at(i, share(series.values[i])));
@@ -5926,7 +5974,7 @@ var RadialChart = class extends LineChart {
5926
5974
  super.show(index);
5927
5975
  this._rings.forEach((ring, i) => ring.classList.toggle("active", i === index));
5928
5976
  if (this._tooltip.hidden) return;
5929
- const color = this._color(index);
5977
+ const color = seriesColor(index);
5930
5978
  this._tooltip.querySelectorAll("[data-series]").forEach((span) => {
5931
5979
  span.dataset.series = color;
5932
5980
  });
@@ -5940,9 +5988,6 @@ var RadialChart = class extends LineChart {
5940
5988
  this._tooltip.style.top = `${(50 + y) / (this._gauge ? 50 : 100) * 100}%`;
5941
5989
  this._tooltip.classList.toggle("end", x > 0);
5942
5990
  }
5943
- _color(index) {
5944
- return String(index % COLORS + 1);
5945
- }
5946
5991
  /** A fraction of the ring as a turn clockwise from the top. */
5947
5992
  _turn(fraction) {
5948
5993
  return this._gauge ? fraction / 2 - 0.25 : fraction;
@@ -5956,7 +6001,7 @@ var RadialChart = class extends LineChart {
5956
6001
  const text = this.series[0].text;
5957
6002
  legend.append(...this.labels.map((label, i) => {
5958
6003
  const li = document.createElement("li");
5959
- li.dataset.series = this._color(i);
6004
+ li.dataset.series = seriesColor(i);
5960
6005
  const [name, value] = [label, text[i]].map((content) => {
5961
6006
  const span = document.createElement("span");
5962
6007
  span.textContent = content;
@@ -6009,7 +6054,7 @@ var RadialChart = class extends LineChart {
6009
6054
  return ring2;
6010
6055
  };
6011
6056
  const ring = circle("radial-chart-ring", this._fractions[i], true);
6012
- ring.dataset.series = this._color(i);
6057
+ ring.dataset.series = seriesColor(i);
6013
6058
  if (!this._fractions[i]) ring.classList.add("empty");
6014
6059
  svg.append(circle("radial-chart-track", 1, gauge), ring);
6015
6060
  return ring;
@@ -6063,7 +6108,7 @@ var MixedChart = class extends ColumnChart {
6063
6108
  };
6064
6109
 
6065
6110
  // src/ts/components/select.ts
6066
- var _defaults17 = {
6111
+ var _defaults18 = {
6067
6112
  classes: "",
6068
6113
  menuOptions: {}
6069
6114
  };
@@ -6137,7 +6182,7 @@ var FormSelect = class _FormSelect extends Component {
6137
6182
  ...options
6138
6183
  };
6139
6184
  this.isMultiple = this.el.multiple;
6140
- this.nativeTabIndex = this.el.tabIndex ?? -1;
6185
+ this.nativeTabIndex = this.el.tabIndex;
6141
6186
  this.el.tabIndex = -1;
6142
6187
  this._values = [];
6143
6188
  this._createdWrapper = false;
@@ -6145,7 +6190,7 @@ var FormSelect = class _FormSelect extends Component {
6145
6190
  this._setupEventHandlers();
6146
6191
  }
6147
6192
  static get defaults() {
6148
- return _defaults17;
6193
+ return _defaults18;
6149
6194
  }
6150
6195
  /**
6151
6196
  * Initializes instances of FormSelect.
@@ -6380,13 +6425,13 @@ var FormSelect = class _FormSelect extends Component {
6380
6425
  if (selectedOption.id) this.input.setAttribute("aria-activedescendant", selectedOption.id);
6381
6426
  }
6382
6427
  this.input.ariaExpanded = "true";
6383
- if (userOnOpenEnd && typeof userOnOpenEnd === "function")
6428
+ if (typeof userOnOpenEnd === "function")
6384
6429
  userOnOpenEnd.call(this.menu, this.el);
6385
6430
  };
6386
6431
  menuOptions.onCloseEnd = () => {
6387
6432
  this.input.ariaExpanded = "false";
6388
6433
  this.input.removeAttribute("aria-activedescendant");
6389
- if (userOnCloseEnd && typeof userOnCloseEnd === "function")
6434
+ if (typeof userOnCloseEnd === "function")
6390
6435
  userOnCloseEnd.call(this.menu, this.el);
6391
6436
  };
6392
6437
  menuOptions.closeOnClick = false;
@@ -6536,10 +6581,7 @@ var FormSelect = class _FormSelect extends Component {
6536
6581
  else this._selectValue(value);
6537
6582
  }
6538
6583
  _getSelectedOptions() {
6539
- return Array.prototype.filter.call(
6540
- this.el.selectedOptions,
6541
- (realOption) => realOption
6542
- );
6584
+ return Array.from(this.el.selectedOptions);
6543
6585
  }
6544
6586
  _setValueToInput() {
6545
6587
  this.input.value = this._getSelectedOptions().map((option) => option.textContent.trim()).join(", ");
@@ -6570,7 +6612,7 @@ var FormSelect = class _FormSelect extends Component {
6570
6612
  };
6571
6613
 
6572
6614
  // src/ts/plugins/dockedDisplayPlugin.ts
6573
- var _defaults18 = {
6615
+ var _defaults19 = {
6574
6616
  margin: 5,
6575
6617
  transition: 10,
6576
6618
  duration: 250,
@@ -6579,9 +6621,9 @@ var _defaults18 = {
6579
6621
  var DockedDisplayPlugin = class _DockedDisplayPlugin {
6580
6622
  constructor(el, container, options) {
6581
6623
  this._handleDocumentClick = (e) => {
6582
- if (this.visible && !e.composedPath().includes(this.el) && !e.composedPath().includes(this.container)) {
6583
- this.hide();
6584
- }
6624
+ if (!this.visible) return;
6625
+ const path = e.composedPath();
6626
+ if (!path.includes(this.el) && !path.includes(this.container)) this.hide();
6585
6627
  };
6586
6628
  /**
6587
6629
  * Tears the plugin down. While shown, the document listener holds a
@@ -6598,12 +6640,10 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
6598
6640
  document.addEventListener("click", this._handleDocumentClick);
6599
6641
  const coordinates = Utils._setAbsolutePosition(this.el, this.container, "bottom", this.options.margin, this.options.transition, this.options.align);
6600
6642
  this.container.style.visibility = "visible";
6601
- this.container.style.transition = `
6602
- transform ${this.options.duration}ms ease-out,
6603
- opacity ${this.options.duration}ms ease-out`;
6643
+ this.container.style.transition = this._transition;
6604
6644
  setTimeout(() => {
6605
6645
  this.container.style.transform = `translateX(${coordinates.x}px) translateY(${coordinates.y}px)`;
6606
- this.container.style.opacity = 1 .toString();
6646
+ this.container.style.opacity = "1";
6607
6647
  }, 1);
6608
6648
  };
6609
6649
  this.hide = () => {
@@ -6611,9 +6651,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
6611
6651
  this.visible = false;
6612
6652
  document.removeEventListener("click", this._handleDocumentClick);
6613
6653
  this.container.removeAttribute("style");
6614
- this.container.style.transition = `
6615
- transform ${this.options.duration}ms ease-out,
6616
- opacity ${this.options.duration}ms ease-out`;
6654
+ this.container.style.transition = this._transition;
6617
6655
  setTimeout(() => {
6618
6656
  this.container.style.transform = `translateX(0px) translateY(0px)`;
6619
6657
  this.container.style.opacity = "0";
@@ -6621,7 +6659,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
6621
6659
  };
6622
6660
  this.el = el;
6623
6661
  this.options = {
6624
- ..._defaults18,
6662
+ ..._defaults19,
6625
6663
  ...options
6626
6664
  };
6627
6665
  this.container = document.createElement("div");
@@ -6629,6 +6667,13 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
6629
6667
  this.container.append(container);
6630
6668
  el.parentElement.append(this.container);
6631
6669
  }
6670
+ // @todo move to Util? -> duplicate code fragment with tooltip
6671
+ // easeOutCubic
6672
+ get _transition() {
6673
+ return `
6674
+ transform ${this.options.duration}ms ease-out,
6675
+ opacity ${this.options.duration}ms ease-out`;
6676
+ }
6632
6677
  /**
6633
6678
  * Initializes instance of DockedDisplayPlugin
6634
6679
  * @param el HTMLElement to position to
@@ -6641,7 +6686,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
6641
6686
  };
6642
6687
 
6643
6688
  // src/ts/components/datepicker.ts
6644
- var _defaults19 = {
6689
+ var _defaults20 = {
6645
6690
  // the default output format for the input field value
6646
6691
  format: "mmm dd, yyyy",
6647
6692
  // Used to create date object from current input string
@@ -6745,6 +6790,8 @@ var _Datepicker = class _Datepicker extends Component {
6745
6790
  constructor(el, options) {
6746
6791
  super(el, options, _Datepicker);
6747
6792
  this.multiple = false;
6793
+ /** What setInputValue last wrote, so reading it back does not depend on the parser. */
6794
+ this._writtenInputs = /* @__PURE__ */ new WeakMap();
6748
6795
  /** Rows renderRow has already checked, so renderBody does not parse them again. */
6749
6796
  this._checkedRows = /* @__PURE__ */ new Set();
6750
6797
  /** Nesting depth of {@link _batchDraws}; > 0 means draws are being collected. */
@@ -6827,7 +6874,7 @@ var _Datepicker = class _Datepicker extends Component {
6827
6874
  e.target.getAttribute("data-month"),
6828
6875
  e.target.getAttribute("data-day")
6829
6876
  );
6830
- if (!this.multiple || this.multiple && this.options.isMultipleSelection) {
6877
+ if (!this.multiple || this.options.isMultipleSelection) {
6831
6878
  this.setDate(selectedDate);
6832
6879
  }
6833
6880
  if (this.options.isDateRange) {
@@ -6925,12 +6972,12 @@ var _Datepicker = class _Datepicker extends Component {
6925
6972
  }
6926
6973
  }
6927
6974
  }
6928
- if (this.options.displayPlugin) {
6929
- if (this.options.displayPlugin === "docked") this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
6975
+ if (this.options.displayPlugin === "docked") {
6976
+ this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
6930
6977
  }
6931
6978
  }
6932
6979
  static get defaults() {
6933
- return _defaults19;
6980
+ return _defaults20;
6934
6981
  }
6935
6982
  /**
6936
6983
  * Initializes instances of Datepicker.
@@ -7083,7 +7130,8 @@ var _Datepicker = class _Datepicker extends Component {
7083
7130
  this.draw();
7084
7131
  return;
7085
7132
  }
7086
- const parsedDate = this._parseInput(el.value);
7133
+ const written = !this.options.parse && this._writtenInputs.get(el);
7134
+ const parsedDate = written && written.value === el.value ? written.date : this._parseInput(el.value);
7087
7135
  if (!_Datepicker._isDate(parsedDate)) return;
7088
7136
  const date = new Date(parsedDate.getTime());
7089
7137
  _Datepicker._setToStartOfDay(date);
@@ -7141,7 +7189,7 @@ var _Datepicker = class _Datepicker extends Component {
7141
7189
  setSingleDate(date, isEndDate) {
7142
7190
  if (!isEndDate) {
7143
7191
  this.date = date;
7144
- } else if (isEndDate) {
7192
+ } else {
7145
7193
  this.endDate = date;
7146
7194
  }
7147
7195
  }
@@ -7150,13 +7198,11 @@ var _Datepicker = class _Datepicker extends Component {
7150
7198
  * @param date Date to set on the datepicker.
7151
7199
  */
7152
7200
  setMultiDate(date) {
7153
- const selectedDate = this.dates?.find((item) => {
7154
- return item.getTime() === date.getTime() ? item : false;
7155
- });
7156
- if (!selectedDate) {
7201
+ const index = this.dates.findIndex((item) => item.getTime() === date.getTime());
7202
+ if (index === -1) {
7157
7203
  this.dates.push(date);
7158
7204
  } else {
7159
- this.dates.splice(this.dates.indexOf(selectedDate), 1);
7205
+ this.dates.splice(index, 1);
7160
7206
  }
7161
7207
  this.dates.sort((a, b) => a.getTime() < b.getTime() ? -1 : 0);
7162
7208
  }
@@ -7198,6 +7244,7 @@ var _Datepicker = class _Datepicker extends Component {
7198
7244
  } else {
7199
7245
  el.value = this.toString(date);
7200
7246
  }
7247
+ this._writtenInputs.set(el, { value: el.value, date: _Datepicker._isDate(date) ? new Date(date.getTime()) : null });
7201
7248
  el.dispatchEvent(
7202
7249
  new CustomEvent("change", {
7203
7250
  bubbles: true,
@@ -7282,12 +7329,7 @@ var _Datepicker = class _Datepicker extends Component {
7282
7329
  }
7283
7330
  }
7284
7331
  const previousMonth = month === 0 ? 11 : month - 1, nextMonth = month === 11 ? 0 : month + 1, yearOfPreviousMonth = month === 0 ? year - 1 : year, yearOfNextMonth = month === 11 ? year + 1 : year, daysInPreviousMonth = _Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth);
7285
- let cells = days + before, after = cells;
7286
- while (after > 7) {
7287
- after -= 7;
7288
- }
7289
- cells += 7 - after;
7290
- let isWeekSelected = false;
7332
+ const cells = Math.ceil((days + before) / 7) * 7;
7291
7333
  for (let i = 0, r = 0; i < cells; i++) {
7292
7334
  const day = new Date(year, month, 1 + (i - before)), isToday = _Datepicker._compareDates(day, now), hasEvent = this.options.events.indexOf(day.toDateString()) !== -1, isEmpty = i < before || i >= days + before, isStartRange = this.options.startRange && _Datepicker._compareDates(this.options.startRange, day), isEndRange = this.options.endRange && _Datepicker._compareDates(this.options.endRange, day), isInRange = this.options.startRange && this.options.endRange && this.options.startRange < day && day < this.options.endRange, isDisabled = this.options.minDate && day < this.options.minDate || this.options.maxDate && day > this.options.maxDate || this.options.disableWeekends && _Datepicker._isWeekend(day) || this.options.disableDayFn && this.options.disableDayFn(day), isDateRangeStart = this.options.isDateRange && this.date && this.endDate && _Datepicker._compareDates(this.date, day), isDateRangeEnd = this.options.isDateRange && this.endDate && _Datepicker._compareDates(this.endDate, day), isDateRange = this.options.isDateRange && _Datepicker._isDate(this.date) && _Datepicker._isDate(this.endDate) && _Datepicker._compareWithinRange(day, this.date, this.endDate);
7293
7335
  let dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year;
@@ -7331,10 +7373,9 @@ var _Datepicker = class _Datepicker extends Component {
7331
7373
  };
7332
7374
  row.push(this.renderDay(dayConfig));
7333
7375
  if (++r === 7) {
7334
- data.push(this.renderRow(row, this.options.isRTL, isWeekSelected));
7376
+ data.push(this.renderRow(row, this.options.isRTL, false));
7335
7377
  row = [];
7336
7378
  r = 0;
7337
- isWeekSelected = false;
7338
7379
  }
7339
7380
  }
7340
7381
  return this.renderTable(this.options, data, randId);
@@ -7351,7 +7392,7 @@ var _Datepicker = class _Datepicker extends Component {
7351
7392
  isDateRangeStart: "is-daterange-start",
7352
7393
  isDateRangeEnd: "is-daterange-end",
7353
7394
  isDateRange: "is-daterange"
7354
- }, ariaSelected = !(["isSelected", "isDateRange"].filter((prop) => !!(opts.hasOwnProperty(prop) && opts[prop] === true)).length === 0), arr = ["datepicker-day"];
7395
+ }, ariaSelected = opts.isSelected === true || opts.isDateRange === true, arr = ["datepicker-day"];
7355
7396
  if (opts.isEmpty) {
7356
7397
  if (opts.showDaysInNextAndPreviousMonths) {
7357
7398
  arr.push("is-outside-current-month");
@@ -7393,13 +7434,14 @@ var _Datepicker = class _Datepicker extends Component {
7393
7434
  /** Wrap calendar rows after validating and encoding their contents. */
7394
7435
  renderBody(rows) {
7395
7436
  const html = rows.join("");
7396
- const checked = rows.every((row) => this._checkedRows.has(row));
7437
+ const safeHtml = _Datepicker._calendarMarkup(html, "tbody");
7397
7438
  this._checkedRows.clear();
7398
- return "<tbody>" + (checked ? html : _Datepicker._calendarMarkup(html, "tbody")) + "</tbody>";
7439
+ return "<tbody>" + safeHtml + "</tbody>";
7399
7440
  }
7400
7441
  static _calendarMarkup(html, parent) {
7401
7442
  const template = document.createElement("template");
7402
7443
  template.innerHTML = html;
7444
+ const childOf = { tbody: "tr", tr: "td", td: "button" };
7403
7445
  const attributes = {
7404
7446
  tr: ["class"],
7405
7447
  td: ["class", "data-day", "aria-selected"],
@@ -7413,8 +7455,8 @@ var _Datepicker = class _Datepicker extends Component {
7413
7455
  return _Datepicker._escape(node.textContent);
7414
7456
  }
7415
7457
  if (!(node instanceof HTMLElement)) throw new TypeError("Unsupported calendar row content");
7416
- const tag = node.localName === "tr" ? "tr" : node.localName === "td" ? "td" : node.localName === "button" ? "button" : null;
7417
- if (!tag || !(container === "tbody" && tag === "tr" || container === "tr" && tag === "td" || container === "td" && tag === "button")) {
7458
+ const tag = childOf[container];
7459
+ if (!tag || node.localName !== tag) {
7418
7460
  throw new TypeError("Unsupported calendar row element");
7419
7461
  }
7420
7462
  if ([...node.attributes].some((attr) => !attributes[tag].includes(attr.name))) {
@@ -7538,26 +7580,9 @@ var _Datepicker = class _Datepicker extends Component {
7538
7580
  const active = this.calendarEl.getRootNode().activeElement;
7539
7581
  const restoreDayFocus = active?.matches(".datepicker-day-button") && this.calendarEl.contains(active);
7540
7582
  const restoreArrow = this.calendarEl.contains(active) && active?.matches(".month-prev, .month-next") ? active.classList.contains("month-prev") ? ".month-prev" : ".month-next" : null;
7541
- const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth;
7542
- if (this._y <= minYear) {
7543
- this._y = minYear;
7544
- if (!isNaN(minMonth) && this._m < minMonth) {
7545
- this._m = minMonth;
7546
- }
7547
- }
7548
- if (this._y >= maxYear) {
7549
- this._y = maxYear;
7550
- if (!isNaN(maxMonth) && this._m > maxMonth) {
7551
- this._m = maxMonth;
7552
- }
7553
- }
7554
7583
  const year = this.calendars[0].year;
7555
7584
  const month = this.calendars[0].month;
7556
- if (!this.options.isDateRange) {
7557
- this._renderDateDisplay(this.date);
7558
- } else {
7559
- this._renderDateDisplay(this.date, this.endDate);
7560
- }
7585
+ this._renderDateDisplay(this.date, this.endDate);
7561
7586
  const key = this._controlsCacheKey(year);
7562
7587
  if (key === this._controlsKey && this.calendarEl.querySelector(".datepicker-controls")) {
7563
7588
  this._reuseControls(year, month);
@@ -7612,12 +7637,8 @@ var _Datepicker = class _Datepicker extends Component {
7612
7637
  else this.calendarEl.insertAdjacentHTML("beforeend", html);
7613
7638
  }
7614
7639
  _setupEventHandlers() {
7615
- this.el.addEventListener("click", this._handleInputClick);
7616
- this.el.addEventListener("keydown", this._handleInputKeydown);
7617
- this.el.addEventListener("change", this._handleInputChange);
7618
- this.endDateEl?.addEventListener("click", this._handleInputClick);
7619
- this.endDateEl?.addEventListener("keydown", this._handleInputKeydown);
7620
- this.endDateEl?.addEventListener("change", this._handleInputChange);
7640
+ this._addInputEventHandlers(this.el);
7641
+ if (this.endDateEl) this._addInputEventHandlers(this.endDateEl);
7621
7642
  this.calendarEl.addEventListener("click", this._handleCalendarClick);
7622
7643
  this.calendarEl.addEventListener("keydown", this._handleCalendarKeydown);
7623
7644
  this.calendarEl.addEventListener("focusin", this._handleCalendarFocus);
@@ -7674,6 +7695,11 @@ var _Datepicker = class _Datepicker extends Component {
7674
7695
  this._removeInputEventHandlers(this.endDateEl);
7675
7696
  }
7676
7697
  }
7698
+ _addInputEventHandlers(input) {
7699
+ input.addEventListener("click", this._handleInputClick);
7700
+ input.addEventListener("keydown", this._handleInputKeydown);
7701
+ input.addEventListener("change", this._handleInputChange);
7702
+ }
7677
7703
  _removeInputEventHandlers(input) {
7678
7704
  input.removeEventListener("click", this._handleInputClick);
7679
7705
  input.removeEventListener("keydown", this._handleInputKeydown);
@@ -7730,9 +7756,7 @@ var _Datepicker = class _Datepicker extends Component {
7730
7756
  const dateInput = this.el.cloneNode(true);
7731
7757
  dateInput.removeAttribute("id");
7732
7758
  dateInput.classList.add("no-autoinit");
7733
- dateInput.addEventListener("click", this._handleInputClick);
7734
- dateInput.addEventListener("keydown", this._handleInputKeydown);
7735
- dateInput.addEventListener("change", this._handleInputChange);
7759
+ this._addInputEventHandlers(dateInput);
7736
7760
  this.el.parentElement.appendChild(dateInput);
7737
7761
  return dateInput;
7738
7762
  }
@@ -7751,7 +7775,7 @@ _Datepicker._template = `
7751
7775
  var Datepicker = _Datepicker;
7752
7776
 
7753
7777
  // src/ts/components/messageScroller.ts
7754
- var _defaults20 = {
7778
+ var _defaults21 = {
7755
7779
  autoScroll: true,
7756
7780
  defaultScrollPosition: "end",
7757
7781
  peek: 64
@@ -7874,7 +7898,7 @@ var MessageScroller = class _MessageScroller extends Component {
7874
7898
  this.button?.addEventListener("click", this._handleButtonClick);
7875
7899
  }
7876
7900
  static get defaults() {
7877
- return _defaults20;
7901
+ return _defaults21;
7878
7902
  }
7879
7903
  /**
7880
7904
  * Initializes instances of MessageScroller.
@@ -8032,7 +8056,7 @@ var MessageScroller = class _MessageScroller extends Component {
8032
8056
  };
8033
8057
 
8034
8058
  // src/ts/components/richTextEditor.ts
8035
- var _defaults21 = {
8059
+ var _defaults22 = {
8036
8060
  Editor: null,
8037
8061
  extensions: []
8038
8062
  };
@@ -8112,7 +8136,7 @@ var RichTextEditor = class _RichTextEditor extends Component {
8112
8136
  el.addEventListener("click", this._handleClick);
8113
8137
  }
8114
8138
  static get defaults() {
8115
- return _defaults21;
8139
+ return _defaults22;
8116
8140
  }
8117
8141
  /**
8118
8142
  * Initializes instances of RichTextEditor.
@@ -8146,7 +8170,7 @@ var RichTextEditor = class _RichTextEditor extends Component {
8146
8170
 
8147
8171
  // src/ts/components/mapView.ts
8148
8172
  var OPENFREEMAP = "https://tiles.openfreemap.org/styles/";
8149
- var _defaults22 = {
8173
+ var _defaults23 = {
8150
8174
  maplibregl: null,
8151
8175
  style: { light: `${OPENFREEMAP}positron`, dark: `${OPENFREEMAP}dark` },
8152
8176
  center: [0, 20],
@@ -8284,7 +8308,7 @@ var MapView = class _MapView extends Component {
8284
8308
  this._sync();
8285
8309
  }
8286
8310
  static get defaults() {
8287
- return _defaults22;
8311
+ return _defaults23;
8288
8312
  }
8289
8313
  /**
8290
8314
  * Initializes instances of MapView.
@@ -8357,6 +8381,13 @@ var MapView = class _MapView extends Component {
8357
8381
  const reset = () => {
8358
8382
  this.map.getCanvas().style.cursor = "";
8359
8383
  };
8384
+ const listen = (method) => {
8385
+ this.map[method]("click", clusters, zoomIn);
8386
+ for (const layer of [clusters, points]) {
8387
+ this.map[method]("mouseenter", layer, pointer);
8388
+ this.map[method]("mouseleave", layer, reset);
8389
+ }
8390
+ };
8360
8391
  this._draw(id, {
8361
8392
  draw: () => {
8362
8393
  const color = options.color ?? this._color("var(--md-comp-map-cluster-color)");
@@ -8401,19 +8432,9 @@ var MapView = class _MapView extends Component {
8401
8432
  paint: { "circle-color": color, "circle-radius": 6, "circle-stroke-width": 2, "circle-stroke-color": surface }
8402
8433
  });
8403
8434
  },
8404
- off: () => {
8405
- this.map.off("click", clusters, zoomIn);
8406
- for (const layer of [clusters, points]) {
8407
- this.map.off("mouseenter", layer, pointer);
8408
- this.map.off("mouseleave", layer, reset);
8409
- }
8410
- }
8435
+ off: () => listen("off")
8411
8436
  });
8412
- this.map.on("click", clusters, zoomIn);
8413
- for (const layer of [clusters, points]) {
8414
- this.map.on("mouseenter", layer, pointer);
8415
- this.map.on("mouseleave", layer, reset);
8416
- }
8437
+ listen("on");
8417
8438
  }
8418
8439
  /** Removes a route, arcs or clusters added with this id. */
8419
8440
  removeOverlay(id) {
@@ -8532,7 +8553,7 @@ var MapView = class _MapView extends Component {
8532
8553
  };
8533
8554
 
8534
8555
  // src/ts/components/lightbox.ts
8535
- var _defaults23 = {
8556
+ var _defaults24 = {
8536
8557
  inDuration: 275,
8537
8558
  outDuration: 200,
8538
8559
  onOpenStart: null,
@@ -8562,9 +8583,6 @@ var _Lightbox = class _Lightbox extends Component {
8562
8583
  for (const el of [this.el, this._overlay, this._photoCaption]) if (el) el.style.transition = "none";
8563
8584
  }
8564
8585
  };
8565
- this._handleLightboxClick = () => {
8566
- this._handleLightboxToggle();
8567
- };
8568
8586
  this._handleLightboxKeypress = (e) => {
8569
8587
  if (this._trigger === this.el && (e.key === Utils.keys.ENTER || e.key === " ")) {
8570
8588
  e.preventDefault();
@@ -8575,10 +8593,7 @@ var _Lightbox = class _Lightbox extends Component {
8575
8593
  if (this._isOpen) this.close();
8576
8594
  else this.open();
8577
8595
  };
8578
- this._handleWindowScroll = () => {
8579
- if (this.overlayActive) this.close();
8580
- };
8581
- this._handleWindowResize = () => {
8596
+ this._handleWindowChange = () => {
8582
8597
  if (this.overlayActive) this.close();
8583
8598
  };
8584
8599
  this._handleWindowEscape = (e) => {
@@ -8626,8 +8641,6 @@ var _Lightbox = class _Lightbox extends Component {
8626
8641
  if (this.caption !== "") this._addCaption();
8627
8642
  const widthPercent = this.originalWidth / this.windowWidth;
8628
8643
  const heightPercent = this.originalHeight / this.windowHeight;
8629
- this.newWidth = 0;
8630
- this.newHeight = 0;
8631
8644
  if (widthPercent > heightPercent) {
8632
8645
  const ratio = this.originalHeight / this.originalWidth;
8633
8646
  this.newWidth = this.windowWidth * 0.9;
@@ -8637,8 +8650,8 @@ var _Lightbox = class _Lightbox extends Component {
8637
8650
  this.newWidth = this.windowHeight * 0.9 * ratio;
8638
8651
  this.newHeight = this.windowHeight * 0.9;
8639
8652
  }
8640
- window.addEventListener("scroll", this._handleWindowScroll, { passive: true });
8641
- window.addEventListener("resize", this._handleWindowResize, { passive: true });
8653
+ window.addEventListener("scroll", this._handleWindowChange, { passive: true });
8654
+ window.addEventListener("resize", this._handleWindowChange, { passive: true });
8642
8655
  window.addEventListener("keyup", this._handleWindowEscape);
8643
8656
  this._animateImageIn();
8644
8657
  };
@@ -8653,11 +8666,11 @@ var _Lightbox = class _Lightbox extends Component {
8653
8666
  if (typeof this.options.onCloseStart === "function")
8654
8667
  this.options.onCloseStart.call(this, this.el);
8655
8668
  if (revision !== this._revision) return;
8656
- window.removeEventListener("scroll", this._handleWindowScroll);
8657
- window.removeEventListener("resize", this._handleWindowResize);
8669
+ window.removeEventListener("scroll", this._handleWindowChange);
8670
+ window.removeEventListener("resize", this._handleWindowChange);
8658
8671
  window.removeEventListener("keyup", this._handleWindowEscape);
8659
- if (this._overlay) this._removeOverlay();
8660
- if (this._photoCaption) this._removeCaption();
8672
+ if (this._overlay) this._fadeOut(this._overlay);
8673
+ if (this._photoCaption) this._fadeOut(this._photoCaption);
8661
8674
  this._animateImageOut();
8662
8675
  };
8663
8676
  this.el["Expressive_Lightbox"] = this;
@@ -8681,7 +8694,7 @@ var _Lightbox = class _Lightbox extends Component {
8681
8694
  this._setupEventHandlers();
8682
8695
  }
8683
8696
  static get defaults() {
8684
- return _defaults23;
8697
+ return _defaults24;
8685
8698
  }
8686
8699
  /**
8687
8700
  * Initializes instances of Lightbox.
@@ -8711,8 +8724,8 @@ var _Lightbox = class _Lightbox extends Component {
8711
8724
  this.el["Expressive_Lightbox"] = void 0;
8712
8725
  }
8713
8726
  _reset() {
8714
- window.removeEventListener("scroll", this._handleWindowScroll);
8715
- window.removeEventListener("resize", this._handleWindowResize);
8727
+ window.removeEventListener("scroll", this._handleWindowChange);
8728
+ window.removeEventListener("resize", this._handleWindowChange);
8716
8729
  window.removeEventListener("keyup", this._handleWindowEscape);
8717
8730
  this._overlay?.remove();
8718
8731
  this._photoCaption?.remove();
@@ -8724,8 +8737,8 @@ var _Lightbox = class _Lightbox extends Component {
8724
8737
  }
8725
8738
  }
8726
8739
  this._changedAncestorList = [];
8727
- if (this.attrWidth !== null && this.attrWidth !== void 0) this.el.setAttribute("width", this.attrWidth);
8728
- if (this.attrHeight !== null && this.attrHeight !== void 0) this.el.setAttribute("height", this.attrHeight);
8740
+ if (this.attrWidth != null) this.el.setAttribute("width", this.attrWidth);
8741
+ if (this.attrHeight != null) this.el.setAttribute("height", this.attrHeight);
8729
8742
  this.el.classList.remove("active");
8730
8743
  this.placeholder.removeAttribute("style");
8731
8744
  if (this.originInlineStyles === null) this.el.removeAttribute("style");
@@ -8752,18 +8765,18 @@ var _Lightbox = class _Lightbox extends Component {
8752
8765
  }
8753
8766
  _setupEventHandlers() {
8754
8767
  this._motion.addEventListener("change", this._handleMotionChange);
8755
- this._trigger.addEventListener("click", this._handleLightboxClick);
8768
+ this._trigger.addEventListener("click", this._handleLightboxToggle);
8756
8769
  this.el.addEventListener("keydown", this._handleLightboxKeypress);
8757
8770
  }
8758
8771
  _removeEventHandlers() {
8759
8772
  this._motion.removeEventListener("change", this._handleMotionChange);
8760
- this._trigger.removeEventListener("click", this._handleLightboxClick);
8773
+ this._trigger.removeEventListener("click", this._handleLightboxToggle);
8761
8774
  this.el.removeEventListener("keydown", this._handleLightboxKeypress);
8762
8775
  }
8763
8776
  _makeAncestorsOverflowVisible() {
8764
8777
  this._changedAncestorList = [];
8765
8778
  let ancestor = this.placeholder.parentNode;
8766
- while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
8779
+ while (ancestor != null && ancestor !== document) {
8767
8780
  const curr = ancestor;
8768
8781
  if (curr.style && (curr.style.overflow !== "visible" || _Lightbox._overflow.has(curr))) {
8769
8782
  const saved = _Lightbox._overflow.get(curr) ?? { count: 0, value: curr.style.overflow, priority: curr.style.getPropertyPriority("overflow") };
@@ -8837,18 +8850,7 @@ var _Lightbox = class _Lightbox extends Component {
8837
8850
  this._photoCaption.innerText = this.caption;
8838
8851
  Utils.portalRoot(this.el).append(this._photoCaption);
8839
8852
  this._photoCaption.style.display = "inline";
8840
- this._photoCaption.style.transition = "none";
8841
- this._photoCaption.style.opacity = "0";
8842
- const duration = this._motion.matches ? 0 : this.options.inDuration;
8843
- this._schedule(() => {
8844
- this._photoCaption.style.transition = `opacity ${duration}ms ease`;
8845
- this._photoCaption.style.opacity = "1";
8846
- }, 1);
8847
- }
8848
- _removeCaption() {
8849
- const duration = this._motion.matches ? 0 : this.options.outDuration;
8850
- this._photoCaption.style.transition = `opacity ${duration}ms ease`;
8851
- this._photoCaption.style.opacity = "0";
8853
+ this._fadeIn(this._photoCaption);
8852
8854
  }
8853
8855
  // Overlay
8854
8856
  _addOverlay() {
@@ -8868,18 +8870,21 @@ var _Lightbox = class _Lightbox extends Component {
8868
8870
  this._overlay.style.height = this.windowHeight + "px";
8869
8871
  this._overlay.style.left = -1 * overlayOffset.left + "px";
8870
8872
  this._overlay.style.top = -1 * overlayOffset.top + "px";
8871
- this._overlay.style.transition = "none";
8872
- this._overlay.style.opacity = "0";
8873
+ this._fadeIn(this._overlay);
8874
+ }
8875
+ _fadeIn(el) {
8876
+ el.style.transition = "none";
8877
+ el.style.opacity = "0";
8873
8878
  const duration = this._motion.matches ? 0 : this.options.inDuration;
8874
8879
  this._schedule(() => {
8875
- this._overlay.style.transition = `opacity ${duration}ms ease`;
8876
- this._overlay.style.opacity = "1";
8880
+ el.style.transition = `opacity ${duration}ms ease`;
8881
+ el.style.opacity = "1";
8877
8882
  }, 1);
8878
8883
  }
8879
- _removeOverlay() {
8884
+ _fadeOut(el) {
8880
8885
  const duration = this._motion.matches ? 0 : this.options.outDuration;
8881
- this._overlay.style.transition = `opacity ${duration}ms ease`;
8882
- this._overlay.style.opacity = "0";
8886
+ el.style.transition = `opacity ${duration}ms ease`;
8887
+ el.style.opacity = "0";
8883
8888
  }
8884
8889
  };
8885
8890
  _Lightbox._overflow = /* @__PURE__ */ new WeakMap();
@@ -8887,7 +8892,7 @@ var Lightbox = _Lightbox;
8887
8892
 
8888
8893
  // src/ts/components/scrollspy.ts
8889
8894
  var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
8890
- var _defaults24 = {
8895
+ var _defaults25 = {
8891
8896
  scrollOffset: 200,
8892
8897
  activeClass: "active",
8893
8898
  getActiveElement: _defaultGetActiveElement,
@@ -8923,7 +8928,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
8923
8928
  }
8924
8929
  }
8925
8930
  static get defaults() {
8926
- return _defaults24;
8931
+ return _defaults25;
8927
8932
  }
8928
8933
  static init(els, options = {}) {
8929
8934
  return super.init(els, options, _ScrollSpy);
@@ -9002,11 +9007,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
9002
9007
  }
9003
9008
  }
9004
9009
  const href = `#${id}`;
9005
- const links = document.querySelectorAll('a[href^="#"]');
9006
- for (let i = 0; i < links.length; i++) {
9007
- if (links[i].getAttribute("href") === href) return links[i];
9008
- }
9009
- return null;
9010
+ return Array.from(document.querySelectorAll('a[href^="#"]')).find((link) => link.getAttribute("href") === href) ?? null;
9010
9011
  }
9011
9012
  };
9012
9013
  _ScrollSpy._elements = [];
@@ -9014,13 +9015,18 @@ _ScrollSpy._active = /* @__PURE__ */ new Map();
9014
9015
  var ScrollSpy = _ScrollSpy;
9015
9016
 
9016
9017
  // src/ts/components/navigationRail.ts
9017
- var _defaults25 = {
9018
+ var _defaults26 = {
9018
9019
  onOpenStart: null,
9019
9020
  onOpenEnd: null,
9020
9021
  onCloseStart: null,
9021
9022
  onCloseEnd: null
9022
9023
  };
9023
9024
  var COMPACT = "(width < 600px)";
9025
+ function deepActiveElement(root) {
9026
+ let active = root.activeElement;
9027
+ while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
9028
+ return active;
9029
+ }
9024
9030
  var NavigationRail = class _NavigationRail extends Component {
9025
9031
  constructor(el, options) {
9026
9032
  super(el, options, _NavigationRail);
@@ -9064,7 +9070,7 @@ var NavigationRail = class _NavigationRail extends Component {
9064
9070
  this._onClick = (e) => {
9065
9071
  const target = e.target;
9066
9072
  if (!(target instanceof Node)) return;
9067
- if (this._toggle && (target === this._toggle || this._toggle.contains(target))) {
9073
+ if (this._toggle?.contains(target)) {
9068
9074
  this.toggle();
9069
9075
  e.preventDefault();
9070
9076
  return;
@@ -9078,12 +9084,9 @@ var NavigationRail = class _NavigationRail extends Component {
9078
9084
  if (this.isExpanded && this._isModal()) {
9079
9085
  const root = this.el.getRootNode();
9080
9086
  const restoreFocus = this.el.contains(root.activeElement);
9081
- let focused = root.activeElement;
9082
- while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;
9087
+ const focused = deepActiveElement(root);
9083
9088
  this.collapse();
9084
- let active = root.activeElement;
9085
- while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
9086
- if (!this.isExpanded && restoreFocus && active === focused) {
9089
+ if (!this.isExpanded && restoreFocus && deepActiveElement(root) === focused) {
9087
9090
  this._toggle?.focus();
9088
9091
  }
9089
9092
  }
@@ -9101,7 +9104,7 @@ var NavigationRail = class _NavigationRail extends Component {
9101
9104
  document.addEventListener("keydown", this._onKeyDown);
9102
9105
  }
9103
9106
  static get defaults() {
9104
- return _defaults25;
9107
+ return _defaults26;
9105
9108
  }
9106
9109
  static init(els, options = {}) {
9107
9110
  return super.init(els, options, _NavigationRail);
@@ -9131,7 +9134,7 @@ var NavigationRail = class _NavigationRail extends Component {
9131
9134
  };
9132
9135
 
9133
9136
  // src/ts/components/tabs.ts
9134
- var _defaults26 = {
9137
+ var _defaults27 = {
9135
9138
  duration: 300,
9136
9139
  onShow: null,
9137
9140
  swipeable: false,
@@ -9148,12 +9151,7 @@ var Tabs = class _Tabs extends Component {
9148
9151
  // and right positions are both read before either is written.
9149
9152
  this._handleWindowResize = Utils.throttle(() => {
9150
9153
  this._setTabsAndTabWidth();
9151
- if (this._tabWidth !== 0 && this._tabsWidth !== 0) {
9152
- const left = this._calcLeftPos(this._activeTabLink);
9153
- const right = this._calcRightPos(this._activeTabLink);
9154
- this._indicator.style.left = left + "px";
9155
- this._indicator.style.right = right + "px";
9156
- }
9154
+ if (this._tabWidth !== 0 && this._tabsWidth !== 0) this._positionIndicator();
9157
9155
  }, 200);
9158
9156
  this._handleTabClick = (e) => {
9159
9157
  const target = e.target;
@@ -9168,8 +9166,7 @@ var Tabs = class _Tabs extends Component {
9168
9166
  }
9169
9167
  if (tabLink.hasAttribute("target")) return;
9170
9168
  if (this.options.swipeable) {
9171
- const panel = tabLink.hash && document.getElementById(tabLink.hash.slice(1));
9172
- const index = this._tabsCarousel.images.indexOf(panel);
9169
+ const index = this._tabsCarousel.images.indexOf(this._panelFor(tabLink));
9173
9170
  if (index >= 0) this._tabsCarousel.set(index);
9174
9171
  e.preventDefault();
9175
9172
  return;
@@ -9198,10 +9195,13 @@ var Tabs = class _Tabs extends Component {
9198
9195
  ...options
9199
9196
  };
9200
9197
  this._tabLinks = this._queryTabLinks();
9198
+ if (!this._tabLinks.length) {
9199
+ console.error("Tabs: no tab links (an <a> child, or one inside .tab) to show");
9200
+ return;
9201
+ }
9201
9202
  this._tabLinks.forEach((link) => {
9202
9203
  this._originalLinks.set(link, { active: link.classList.contains("active"), current: link.getAttribute("aria-current") });
9203
- if (link.hasAttribute("target")) return;
9204
- const panel = link.hash && document.getElementById(link.hash.slice(1));
9204
+ const panel = this._panelFor(link);
9205
9205
  if (panel) this._originalPanels.set(panel, {
9206
9206
  display: panel.style.display,
9207
9207
  priority: panel.style.getPropertyPriority("display"),
@@ -9209,7 +9209,7 @@ var Tabs = class _Tabs extends Component {
9209
9209
  carousel: panel.classList.contains("carousel-item")
9210
9210
  });
9211
9211
  });
9212
- (_a = this.options).swipeable && (_a.swipeable = window.innerWidth <= this.options.responsiveThreshold);
9212
+ (_a = this.options).swipeable && (_a.swipeable = window.innerWidth <= this.options.responsiveThreshold && this._originalPanels.size > 0);
9213
9213
  this._index = 0;
9214
9214
  this._setupActiveTabLink();
9215
9215
  if (this.options.swipeable) {
@@ -9220,9 +9220,12 @@ var Tabs = class _Tabs extends Component {
9220
9220
  this._setTabsAndTabWidth();
9221
9221
  this._createIndicator();
9222
9222
  this._setupEventHandlers();
9223
+ document.fonts?.ready.then(() => {
9224
+ if (this.el["Expressive_Tabs"] === this) this._handleWindowResize();
9225
+ });
9223
9226
  }
9224
9227
  static get defaults() {
9225
- return _defaults26;
9228
+ return _defaults27;
9226
9229
  }
9227
9230
  /**
9228
9231
  * Initializes instances of Tabs.
@@ -9237,8 +9240,8 @@ var Tabs = class _Tabs extends Component {
9237
9240
  }
9238
9241
  destroy() {
9239
9242
  this._removeEventHandlers();
9240
- this._indicator.remove();
9241
- if (this.options.swipeable) {
9243
+ this._indicator?.remove();
9244
+ if (this._tabsCarousel) {
9242
9245
  this._teardownSwipeableTabs();
9243
9246
  }
9244
9247
  this._originalPanels.forEach((original, panel) => {
@@ -9279,8 +9282,19 @@ var Tabs = class _Tabs extends Component {
9279
9282
  indicator.classList.add("indicator");
9280
9283
  this.el.appendChild(indicator);
9281
9284
  this._indicator = indicator;
9282
- this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + "px";
9283
- this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
9285
+ this._positionIndicator();
9286
+ }
9287
+ /** Reads both positions before writing either. */
9288
+ _positionIndicator() {
9289
+ const left = this._calcLeftPos(this._activeTabLink);
9290
+ const right = this._calcRightPos(this._activeTabLink);
9291
+ this._indicator.style.left = left + "px";
9292
+ this._indicator.style.right = right + "px";
9293
+ }
9294
+ /** The panel a link shows, or null for a `target` link or one without a hash. */
9295
+ _panelFor(a) {
9296
+ if (!a.hash || a.hasAttribute("target")) return null;
9297
+ return document.getElementById(a.hash.slice(1));
9284
9298
  }
9285
9299
  /**
9286
9300
  * Which tab is current, for the eye and for assistive technology.
@@ -9302,31 +9316,20 @@ var Tabs = class _Tabs extends Component {
9302
9316
  tabLink.classList.add("active");
9303
9317
  tabLink.setAttribute("aria-current", "page");
9304
9318
  this._index = Array.from(this._tabLinks).indexOf(tabLink);
9305
- this._content = tabLink.hasAttribute("target") ? null : document.getElementById(tabLink.hash.slice(1));
9319
+ this._content = this._panelFor(tabLink);
9306
9320
  }
9307
9321
  _setupActiveTabLink() {
9308
- this._activeTabLink = Array.from(this._tabLinks).find(
9309
- (a) => a.getAttribute("href") === location.hash
9310
- );
9311
- if (!this._activeTabLink) {
9312
- let activeTabLink = this.el.querySelector("a.active");
9313
- if (!activeTabLink) {
9314
- activeTabLink = this._tabLinks[0];
9315
- }
9316
- this._activeTabLink = activeTabLink;
9317
- }
9322
+ this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute("href") === location.hash) ?? this.el.querySelector("a.active") ?? this._tabLinks[0];
9318
9323
  this._setActiveTabLink(this._activeTabLink);
9319
9324
  this._originalPanels.forEach((_, panel) => panel.classList.toggle("active", panel === this._content));
9320
9325
  }
9321
9326
  _setupSwipeableTabs() {
9322
9327
  const tabsContent = [];
9323
9328
  this._tabLinks.forEach((a) => {
9324
- if (a.hash && !a.hasAttribute("target")) {
9325
- const currContent = document.getElementById(a.hash.slice(1));
9326
- if (!currContent) return;
9327
- currContent.classList.add("carousel-item");
9328
- tabsContent.push(currContent);
9329
- }
9329
+ const currContent = this._panelFor(a);
9330
+ if (!currContent) return;
9331
+ currContent.classList.add("carousel-item");
9332
+ tabsContent.push(currContent);
9330
9333
  });
9331
9334
  const tabsWrapper = document.createElement("div");
9332
9335
  tabsWrapper.classList.add("tabs-content", "carousel", "flat");
@@ -9360,11 +9363,9 @@ var Tabs = class _Tabs extends Component {
9360
9363
  }
9361
9364
  _setupNormalTabs() {
9362
9365
  Array.from(this._tabLinks).forEach((a) => {
9363
- if (a === this._activeTabLink || a.hasAttribute("target")) return;
9364
- if (a.hash) {
9365
- const currContent = document.getElementById(a.hash.slice(1));
9366
- if (currContent) currContent.style.display = "none";
9367
- }
9366
+ if (a === this._activeTabLink) return;
9367
+ const currContent = this._panelFor(a);
9368
+ if (currContent) currContent.style.display = "none";
9368
9369
  });
9369
9370
  }
9370
9371
  _setTabsAndTabWidth() {
@@ -9393,23 +9394,20 @@ var Tabs = class _Tabs extends Component {
9393
9394
  this._indicator.style.transition = `
9394
9395
  left ${this.options.duration}ms ease-out ${leftDelay}ms,
9395
9396
  right ${this.options.duration}ms ease-out ${rightDelay}ms`;
9396
- this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + "px";
9397
- this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
9397
+ this._positionIndicator();
9398
9398
  }
9399
9399
  /**
9400
9400
  * Show tab content that corresponds to the tab with the id.
9401
9401
  * @param tabId The id of the tab that you want to switch to.
9402
9402
  */
9403
9403
  select(tabId) {
9404
- const tab = Array.from(this._tabLinks).find(
9405
- (a) => a.getAttribute("href") === "#" + tabId
9406
- );
9404
+ const tab = Array.from(this._tabLinks).find((a) => a.getAttribute("href") === "#" + tabId);
9407
9405
  if (tab) tab.click();
9408
9406
  }
9409
9407
  };
9410
9408
 
9411
9409
  // src/ts/components/timepicker.ts
9412
- var _defaults27 = {
9410
+ var _defaults28 = {
9413
9411
  dialRadius: 135,
9414
9412
  outerRadius: 105,
9415
9413
  innerRadius: 70,
@@ -9492,8 +9490,7 @@ var _Timepicker = class _Timepicker extends Component {
9492
9490
  if (e.pointerId !== this._dragPointerId) return;
9493
9491
  this._dragPointerId = null;
9494
9492
  e.preventDefault();
9495
- document.removeEventListener("pointerup", this._handleDocumentClickEnd);
9496
- document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
9493
+ this._removeDragListeners();
9497
9494
  const x = e.clientX - this.x0;
9498
9495
  const y = e.clientY - this.y0;
9499
9496
  if (this.moved && x === this.dx && y === this.dy) {
@@ -9512,7 +9509,6 @@ var _Timepicker = class _Timepicker extends Component {
9512
9509
  if (typeof this.options.onSelect === "function") {
9513
9510
  this.options.onSelect.call(this, this.hours, this.minutes);
9514
9511
  }
9515
- document.removeEventListener("pointermove", this._handleDocumentClickMove);
9516
9512
  };
9517
9513
  /**
9518
9514
  * A cancelled pointer is not a completed selection. The browser or the OS
@@ -9524,9 +9520,7 @@ var _Timepicker = class _Timepicker extends Component {
9524
9520
  if (e.pointerId !== this._dragPointerId) return;
9525
9521
  this._dragPointerId = null;
9526
9522
  this.moved = false;
9527
- document.removeEventListener("pointermove", this._handleDocumentClickMove);
9528
- document.removeEventListener("pointerup", this._handleDocumentClickEnd);
9529
- document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
9523
+ this._removeDragListeners();
9530
9524
  };
9531
9525
  this._handleAmPmClick = (e) => {
9532
9526
  this._handleAmPmInteraction(e.target);
@@ -9600,12 +9594,12 @@ var _Timepicker = class _Timepicker extends Component {
9600
9594
  this._setupVariables();
9601
9595
  this._setupEventHandlers();
9602
9596
  this._pickerSetup();
9603
- if (this.options.displayPlugin) {
9604
- if (this.options.displayPlugin === "docked") this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
9597
+ if (this.options.displayPlugin === "docked") {
9598
+ this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
9605
9599
  }
9606
9600
  }
9607
9601
  static get defaults() {
9608
- return _defaults27;
9602
+ return _defaults28;
9609
9603
  }
9610
9604
  /**
9611
9605
  * Initializes instances of Timepicker.
@@ -9649,6 +9643,9 @@ var _Timepicker = class _Timepicker extends Component {
9649
9643
  this.digitalClock.removeEventListener("input", this._inputFromTextField);
9650
9644
  this.el.removeEventListener("click", this._handleInputClick);
9651
9645
  this.el.removeEventListener("keydown", this._handleInputKeydown);
9646
+ this._removeDragListeners();
9647
+ }
9648
+ _removeDragListeners() {
9652
9649
  document.removeEventListener("pointermove", this._handleDocumentClickMove);
9653
9650
  document.removeEventListener("pointerup", this._handleDocumentClickEnd);
9654
9651
  document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
@@ -9780,25 +9777,22 @@ var _Timepicker = class _Timepicker extends Component {
9780
9777
  }
9781
9778
  }
9782
9779
  _buildHoursTick(i, radian, radius) {
9783
- const tick = document.createElement("div");
9784
- tick.classList.add("timepicker-tick");
9785
- tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + "px";
9786
- tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + "px";
9787
- tick.textContent = i === 0 ? "00" : i.toString();
9788
- this.hoursView.appendChild(tick);
9780
+ this._placeTick(this.hoursView, radian, radius, i === 0 ? "00" : i.toString());
9789
9781
  }
9790
9782
  _buildMinutesView() {
9791
- const _tick = document.createElement("div");
9792
- _tick.classList.add("timepicker-tick");
9793
9783
  for (let i = 0; i < 60; i += 5) {
9794
- const tick = _tick.cloneNode(true);
9795
9784
  const radian = i / 30 * Math.PI;
9796
- tick.style.left = this.options.dialRadius + Math.sin(radian) * this.options.outerRadius - this.options.tickRadius + "px";
9797
- tick.style.top = this.options.dialRadius - Math.cos(radian) * this.options.outerRadius - this.options.tickRadius + "px";
9798
- tick.textContent = _Timepicker._addLeadingZero(i);
9799
- this.minutesView.appendChild(tick);
9785
+ this._placeTick(this.minutesView, radian, this.options.outerRadius, _Timepicker._addLeadingZero(i));
9800
9786
  }
9801
9787
  }
9788
+ _placeTick(view, radian, radius, text) {
9789
+ const tick = document.createElement("div");
9790
+ tick.classList.add("timepicker-tick");
9791
+ tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + "px";
9792
+ tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + "px";
9793
+ tick.textContent = text;
9794
+ view.appendChild(tick);
9795
+ }
9802
9796
  _updateAmPmView() {
9803
9797
  if (!this._amBtn || !this._pmBtn) return;
9804
9798
  this._amBtn.setAttribute("aria-pressed", String(this.amOrPm === "AM"));
@@ -9865,53 +9859,31 @@ var _Timepicker = class _Timepicker extends Component {
9865
9859
  setHand(x, y, roundBy5 = false) {
9866
9860
  this._cancelClockReset();
9867
9861
  const isHours = this.currentView === "hours", unit = Math.PI / (isHours || roundBy5 ? 6 : 30), z = Math.sqrt(x * x + y * y), inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2;
9868
- let radian = Math.atan2(x, -y), radius = inner ? this.options.innerRadius : this.options.outerRadius;
9869
- if (this.options.twelveHour) {
9870
- radius = this.options.outerRadius;
9871
- }
9862
+ const radius = inner && !this.options.twelveHour ? this.options.innerRadius : this.options.outerRadius;
9863
+ let radian = Math.atan2(x, -y);
9872
9864
  if (radian < 0) {
9873
9865
  radian = Math.PI * 2 + radian;
9874
9866
  }
9875
9867
  let value = Math.round(radian / unit);
9876
9868
  radian = value * unit;
9877
- if (this.options.twelveHour) {
9878
- if (isHours) {
9879
- if (value === 0) value = 12;
9880
- } else {
9881
- if (roundBy5) value *= 5;
9882
- if (value === 60) value = 0;
9883
- }
9884
- } else {
9885
- if (isHours) {
9886
- if (value === 12) {
9887
- value = 0;
9888
- }
9889
- value = inner ? value === 0 ? 12 : value : value === 0 ? 0 : value + 12;
9890
- } else {
9891
- if (roundBy5) {
9892
- value *= 5;
9893
- }
9894
- if (value === 60) {
9895
- value = 0;
9896
- }
9897
- }
9898
- }
9899
- if (this[this.currentView] !== value) {
9900
- if (this.canVibrate && this.options.vibrate) {
9901
- if (!this.vibrateTimer) {
9902
- navigator.vibrate(10);
9903
- this.vibrateTimer = setTimeout(() => {
9904
- this.vibrateTimer = null;
9905
- }, 100);
9906
- }
9907
- }
9869
+ if (!isHours) {
9870
+ if (roundBy5) value *= 5;
9871
+ if (value === 60) value = 0;
9872
+ } else if (this.options.twelveHour) {
9873
+ if (value === 0) value = 12;
9874
+ } else if (value % 12 === 0) {
9875
+ value = inner ? 12 : 0;
9876
+ } else if (!inner) {
9877
+ value += 12;
9878
+ }
9879
+ if (this[this.currentView] !== value && this.canVibrate && this.options.vibrate && !this.vibrateTimer) {
9880
+ navigator.vibrate(10);
9881
+ this.vibrateTimer = setTimeout(() => {
9882
+ this.vibrateTimer = null;
9883
+ }, 100);
9908
9884
  }
9909
9885
  this[this.currentView] = value;
9910
- if (isHours) {
9911
- this.inputHours.value = _Timepicker._addLeadingZero(value);
9912
- } else {
9913
- this.inputMinutes.value = _Timepicker._addLeadingZero(value);
9914
- }
9886
+ (isHours ? this.inputHours : this.inputMinutes).value = _Timepicker._addLeadingZero(value);
9915
9887
  this.setClockAttributes(radian, radius);
9916
9888
  }
9917
9889
  setClockAttributes(radian, radius) {
@@ -9967,7 +9939,7 @@ _Timepicker._template = `<div class="timepicker-container">
9967
9939
  var Timepicker = _Timepicker;
9968
9940
 
9969
9941
  // src/ts/components/snackbar.ts
9970
- var _defaults28 = {
9942
+ var _defaults29 = {
9971
9943
  text: "",
9972
9944
  action: "",
9973
9945
  onAction: null,
@@ -10017,7 +9989,7 @@ var _Snackbar = class _Snackbar {
10017
9989
  this._setTimer();
10018
9990
  }
10019
9991
  static get defaults() {
10020
- return _defaults28;
9992
+ return _defaults29;
10021
9993
  }
10022
9994
  static getInstance(el) {
10023
9995
  return el["Expressive_Snackbar"];
@@ -10090,10 +10062,7 @@ var _Snackbar = class _Snackbar {
10090
10062
  snackbar.wasSwiped = true;
10091
10063
  snackbar.dismiss();
10092
10064
  } else {
10093
- snackbar.el.style.transition = "transform .2s, opacity .2s";
10094
- snackbar.el.style.transform = "";
10095
- snackbar.el.style.opacity = "";
10096
- snackbar._resumeTimer();
10065
+ snackbar._snapBack();
10097
10066
  }
10098
10067
  _Snackbar._draggedSnackbar = null;
10099
10068
  }
@@ -10110,12 +10079,15 @@ var _Snackbar = class _Snackbar {
10110
10079
  if (!snackbar) return;
10111
10080
  snackbar.panning = false;
10112
10081
  snackbar.el.classList.remove("panning");
10113
- snackbar.el.style.transition = "transform .2s, opacity .2s";
10114
- snackbar.el.style.transform = "";
10115
- snackbar.el.style.opacity = "";
10116
- snackbar._resumeTimer();
10082
+ snackbar._snapBack();
10117
10083
  _Snackbar._draggedSnackbar = null;
10118
10084
  }
10085
+ _snapBack() {
10086
+ this.el.style.transition = "transform .2s, opacity .2s";
10087
+ this.el.style.transform = "";
10088
+ this.el.style.opacity = "";
10089
+ this._resumeTimer();
10090
+ }
10119
10091
  /**
10120
10092
  * dismiss all snackbars.
10121
10093
  */
@@ -10285,15 +10257,15 @@ var _Snackbar = class _Snackbar {
10285
10257
  this.counterTimeout = null;
10286
10258
  this._restoreFocus();
10287
10259
  if (this._events.signal.aborted) return;
10288
- const activationDistance = this.el.offsetWidth * this.options.activationPercent;
10260
+ const duration = this.options.outDuration;
10261
+ const transitions = [`margin ${duration}ms ease`, `opacity ${duration}ms ease`];
10289
10262
  if (this.wasSwiped) {
10290
- this.el.style.transition = "transform .05s, opacity .05s";
10291
- this.el.style.transform = `translateX(${activationDistance}px)`;
10263
+ const direction = this.xPos < this.startingXPos ? -1 : 1;
10264
+ this.el.style.transform = `translateX(${direction * this.el.offsetWidth}px)`;
10292
10265
  this.el.style.opacity = "0";
10266
+ transitions.push(`transform ${duration}ms ease`);
10293
10267
  }
10294
- this.el.style.transition = `
10295
- margin ${this.options.outDuration}ms ease,
10296
- opacity ${this.options.outDuration}ms ease`;
10268
+ this.el.style.transition = transitions.join(", ");
10297
10269
  clearTimeout(this._transitionTimer);
10298
10270
  this._transitionTimer = setTimeout(() => {
10299
10271
  this.el.style.opacity = "0";
@@ -10315,7 +10287,7 @@ _Snackbar._draggedSnackbar = null;
10315
10287
  var Snackbar = _Snackbar;
10316
10288
 
10317
10289
  // src/ts/components/tooltip.ts
10318
- var _defaults29 = {
10290
+ var _defaults30 = {
10319
10291
  exitDelay: 200,
10320
10292
  enterDelay: 0,
10321
10293
  text: "",
@@ -10399,7 +10371,7 @@ var Tooltip = class _Tooltip extends Component {
10399
10371
  this._setupEventHandlers();
10400
10372
  }
10401
10373
  static get defaults() {
10402
- return _defaults29;
10374
+ return _defaults30;
10403
10375
  }
10404
10376
  /**
10405
10377
  * Initializes instances of Tooltip.
@@ -10445,8 +10417,12 @@ var Tooltip = class _Tooltip extends Component {
10445
10417
  this.tooltipEl.id = `tooltip-${Utils.guid()}`;
10446
10418
  this.tooltipEl.setAttribute("role", "tooltip");
10447
10419
  this.el.setAttribute("aria-describedby", [this.el.getAttribute("aria-describedby"), this.tooltipEl.id].filter(Boolean).join(" "));
10448
- const tooltipContentEl = this.options.tooltipId ? Utils.getElementById(this.el, this.options.tooltipId) : document.createElement("div");
10449
- if (this.options.tooltipId) {
10420
+ const richContentEl = this.options.tooltipId ? Utils.getElementById(this.el, this.options.tooltipId) : null;
10421
+ if (this.options.tooltipId && !richContentEl) {
10422
+ console.error(`Tooltip: no element with id "${this.options.tooltipId}"; showing the text tooltip instead.`);
10423
+ }
10424
+ const tooltipContentEl = richContentEl ?? document.createElement("div");
10425
+ if (richContentEl) {
10450
10426
  this.tooltipEl.classList.add("rich");
10451
10427
  const marker = document.createComment("");
10452
10428
  tooltipContentEl.before(marker);
@@ -10467,7 +10443,7 @@ var Tooltip = class _Tooltip extends Component {
10467
10443
  Utils.portalRoot(this.el).appendChild(this.tooltipEl);
10468
10444
  }
10469
10445
  _setTooltipContent(tooltipContentEl) {
10470
- if (this.options.tooltipId) return;
10446
+ if (this._originalContent) return;
10471
10447
  tooltipContentEl.innerText = this.options.text;
10472
10448
  }
10473
10449
  _updateTooltipContent() {
@@ -10619,6 +10595,7 @@ var AUTO_INIT_COMPONENTS = {
10619
10595
  Chips: { component: Chips, selector: ".chips" },
10620
10596
  Confetti: { component: Confetti, selector: ".confetti" },
10621
10597
  Particles: { component: Particles, selector: "canvas.particles" },
10598
+ Keypad: { component: Keypad, selector: ".keypad, .keyboard" },
10622
10599
  ColumnChart: { component: ColumnChart, selector: ".column-chart" },
10623
10600
  BarChart: { component: BarChart, selector: ".bar-chart" },
10624
10601
  PieChart: { component: PieChart, selector: ".pie-chart" },
@@ -10677,7 +10654,7 @@ function AutoInit(context = document.body, options) {
10677
10654
  }
10678
10655
 
10679
10656
  // src/ts/modular.ts
10680
- var version = "0.14.1";
10657
+ var version = "0.15.0";
10681
10658
 
10682
10659
  // src/ts/index.ts
10683
10660
  Forms.Init();