@expressivecss/expressive 0.16.0 → 0.17.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 (384) hide show
  1. package/CHANGELOG.md +306 -1
  2. package/README.md +1 -1
  3. package/dist/css/expressive.css +540 -646
  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-PA7NU5AK.mjs → chunk-26VUH75M.mjs} +6 -3
  8. package/dist/js/chunks/chunk-26VUH75M.mjs.map +7 -0
  9. package/dist/js/chunks/{chunk-NBJAUGPP.mjs → chunk-2LFCOGC3.mjs} +12 -23
  10. package/dist/js/chunks/chunk-2LFCOGC3.mjs.map +7 -0
  11. package/dist/js/chunks/{chunk-OP43LLIC.mjs → chunk-36GELQGX.mjs} +4 -4
  12. package/dist/js/chunks/{chunk-OP43LLIC.mjs.map → chunk-36GELQGX.mjs.map} +2 -2
  13. package/dist/js/chunks/{chunk-EC26RU2D.mjs → chunk-3FKWIRHW.mjs} +6 -2
  14. package/dist/js/chunks/chunk-3FKWIRHW.mjs.map +7 -0
  15. package/dist/js/chunks/{chunk-Y6H2X7ZC.mjs → chunk-3KF65KGL.mjs} +3 -3
  16. package/dist/js/chunks/{chunk-4QUCNFSD.mjs → chunk-3KLZRQZI.mjs} +31 -10
  17. package/dist/js/chunks/chunk-3KLZRQZI.mjs.map +7 -0
  18. package/dist/js/chunks/{chunk-75E5EDJF.mjs → chunk-3XORNED5.mjs} +2 -2
  19. package/dist/js/chunks/{chunk-NNHVANQA.mjs → chunk-4WBGAQN3.mjs} +3 -3
  20. package/dist/js/chunks/{chunk-ZJNLAGY5.mjs → chunk-5F4URJHL.mjs} +2 -2
  21. package/dist/js/chunks/{chunk-ZVLOUDIJ.mjs → chunk-67UNY7RH.mjs} +50 -2
  22. package/dist/js/chunks/chunk-67UNY7RH.mjs.map +7 -0
  23. package/dist/js/chunks/{chunk-P6DRQ6KS.mjs → chunk-7CXNATJS.mjs} +6 -5
  24. package/dist/js/chunks/chunk-7CXNATJS.mjs.map +7 -0
  25. package/dist/js/chunks/{chunk-4TRZ2AER.mjs → chunk-7X44MKEQ.mjs} +15 -14
  26. package/dist/js/chunks/chunk-7X44MKEQ.mjs.map +7 -0
  27. package/dist/js/chunks/{chunk-GWZ76SR4.mjs → chunk-7ZAMOMGY.mjs} +12 -7
  28. package/dist/js/chunks/chunk-7ZAMOMGY.mjs.map +7 -0
  29. package/dist/js/chunks/{chunk-GVZQH2H5.mjs → chunk-AEG6LOAJ.mjs} +2 -2
  30. package/dist/js/chunks/{chunk-Y6TLRA3U.mjs → chunk-AQNFCJJ5.mjs} +27 -21
  31. package/dist/js/chunks/chunk-AQNFCJJ5.mjs.map +7 -0
  32. package/dist/js/chunks/{chunk-OUCHKSAW.mjs → chunk-B55LWKBM.mjs} +16 -4
  33. package/dist/js/chunks/chunk-B55LWKBM.mjs.map +7 -0
  34. package/dist/js/chunks/{chunk-AI73GJKG.mjs → chunk-BB5VXYXT.mjs} +2 -2
  35. package/dist/js/chunks/{chunk-2RLBDFH4.mjs → chunk-BDATLH3H.mjs} +4 -4
  36. package/dist/js/chunks/{chunk-2CS6TITK.mjs → chunk-CWMQOT4O.mjs} +23 -10
  37. package/dist/js/chunks/chunk-CWMQOT4O.mjs.map +7 -0
  38. package/dist/js/chunks/{chunk-ZKWUWBUB.mjs → chunk-CY2CTOVM.mjs} +2 -2
  39. package/dist/js/chunks/{chunk-CSYWKEK3.mjs → chunk-DWA5UYLJ.mjs} +58 -27
  40. package/dist/js/chunks/chunk-DWA5UYLJ.mjs.map +7 -0
  41. package/dist/js/chunks/{chunk-CMGXGYUC.mjs → chunk-EB2V4OKL.mjs} +14 -9
  42. package/dist/js/chunks/chunk-EB2V4OKL.mjs.map +7 -0
  43. package/dist/js/chunks/{chunk-Z4GICXR2.mjs → chunk-EWO662ZC.mjs} +5 -7
  44. package/dist/js/chunks/chunk-EWO662ZC.mjs.map +7 -0
  45. package/dist/js/chunks/{chunk-VGY4M57S.mjs → chunk-F7LAKFMX.mjs} +67 -34
  46. package/dist/js/chunks/chunk-F7LAKFMX.mjs.map +7 -0
  47. package/dist/js/chunks/{chunk-67ZPPKXS.mjs → chunk-FNIIH2LU.mjs} +3 -3
  48. package/dist/js/chunks/chunk-GE3YMFS6.mjs +15 -0
  49. package/dist/js/chunks/chunk-GE3YMFS6.mjs.map +7 -0
  50. package/dist/js/chunks/{chunk-DZYVU75J.mjs → chunk-GFWYMWYN.mjs} +18 -14
  51. package/dist/js/chunks/chunk-GFWYMWYN.mjs.map +7 -0
  52. package/dist/js/chunks/{chunk-3L3QIYLC.mjs → chunk-H5ISU45X.mjs} +8 -6
  53. package/dist/js/chunks/chunk-H5ISU45X.mjs.map +7 -0
  54. package/dist/js/chunks/{chunk-QXKWVHBD.mjs → chunk-H6YIKFAQ.mjs} +67 -46
  55. package/dist/js/chunks/chunk-H6YIKFAQ.mjs.map +7 -0
  56. package/dist/js/chunks/{chunk-KZPSAXIU.mjs → chunk-HEH7E3KO.mjs} +22 -12
  57. package/dist/js/chunks/chunk-HEH7E3KO.mjs.map +7 -0
  58. package/dist/js/chunks/{chunk-T3BNSRP3.mjs → chunk-HQRLBTNM.mjs} +3 -3
  59. package/dist/js/chunks/{chunk-NAC72P7R.mjs → chunk-I2F7MLUU.mjs} +2 -2
  60. package/dist/js/chunks/{chunk-ZM3XBHWV.mjs → chunk-IQOTGGHX.mjs} +86 -35
  61. package/dist/js/chunks/chunk-IQOTGGHX.mjs.map +7 -0
  62. package/dist/js/chunks/{chunk-QACZ6TUP.mjs → chunk-JH3YWKA6.mjs} +5 -4
  63. package/dist/js/chunks/chunk-JH3YWKA6.mjs.map +7 -0
  64. package/dist/js/chunks/chunk-JOLJAYIJ.mjs +7 -0
  65. package/dist/js/chunks/{chunk-4IKVPCSU.mjs.map → chunk-JOLJAYIJ.mjs.map} +1 -1
  66. package/dist/js/chunks/{chunk-BPF3I2MN.mjs → chunk-KOTGMCMI.mjs} +9 -2
  67. package/dist/js/chunks/chunk-KOTGMCMI.mjs.map +7 -0
  68. package/dist/js/chunks/{chunk-ANKFWNWT.mjs → chunk-LC4O5LFS.mjs} +3 -3
  69. package/dist/js/chunks/{chunk-4PIXLDNJ.mjs → chunk-LEF33SCP.mjs} +2 -2
  70. package/dist/js/chunks/{chunk-ILDRRG7T.mjs → chunk-LFORZRPH.mjs} +3 -3
  71. package/dist/js/chunks/{chunk-Z4OARDZ7.mjs → chunk-LWLNV5EC.mjs} +26 -17
  72. package/dist/js/chunks/chunk-LWLNV5EC.mjs.map +7 -0
  73. package/dist/js/chunks/{chunk-WU7XJ4RR.mjs → chunk-LXRHUQAX.mjs} +66 -25
  74. package/dist/js/chunks/chunk-LXRHUQAX.mjs.map +7 -0
  75. package/dist/js/chunks/{chunk-VMY55K2X.mjs → chunk-MA2SZZFB.mjs} +11 -7
  76. package/dist/js/chunks/chunk-MA2SZZFB.mjs.map +7 -0
  77. package/dist/js/chunks/{chunk-VJVQIXHC.mjs → chunk-MDBZAMIV.mjs} +8 -10
  78. package/dist/js/chunks/chunk-MDBZAMIV.mjs.map +7 -0
  79. package/dist/js/chunks/{chunk-4EWGD4V2.mjs → chunk-NODZ5VAD.mjs} +2 -2
  80. package/dist/js/chunks/{chunk-UGJHCHXG.mjs → chunk-O2WJB6TH.mjs} +79 -55
  81. package/dist/js/chunks/chunk-O2WJB6TH.mjs.map +7 -0
  82. package/dist/js/chunks/{chunk-7YZ5CN3V.mjs → chunk-PCABY5BN.mjs} +5 -3
  83. package/dist/js/chunks/chunk-PCABY5BN.mjs.map +7 -0
  84. package/dist/js/chunks/{chunk-X7SDA2J5.mjs → chunk-PWKYVMND.mjs} +9 -5
  85. package/dist/js/chunks/{chunk-X7SDA2J5.mjs.map → chunk-PWKYVMND.mjs.map} +2 -2
  86. package/dist/js/chunks/{chunk-SPPHF7YZ.mjs → chunk-QHZZT7YO.mjs} +35 -14
  87. package/dist/js/chunks/chunk-QHZZT7YO.mjs.map +7 -0
  88. package/dist/js/chunks/{chunk-LDXCC2L3.mjs → chunk-QND56EW2.mjs} +5 -4
  89. package/dist/js/chunks/chunk-QND56EW2.mjs.map +7 -0
  90. package/dist/js/chunks/{chunk-NVQ5EHCU.mjs → chunk-QNODAANY.mjs} +4 -4
  91. package/dist/js/chunks/{chunk-7NLUI3RR.mjs → chunk-QRO5FV3I.mjs} +23 -13
  92. package/dist/js/chunks/chunk-QRO5FV3I.mjs.map +7 -0
  93. package/dist/js/chunks/{chunk-FCNF4GRJ.mjs → chunk-R7A7JRC5.mjs} +6 -11
  94. package/dist/js/chunks/chunk-R7A7JRC5.mjs.map +7 -0
  95. package/dist/js/chunks/{chunk-S23RJ3XY.mjs → chunk-RKG2CBFE.mjs} +4 -16
  96. package/dist/js/chunks/chunk-RKG2CBFE.mjs.map +7 -0
  97. package/dist/js/chunks/{chunk-6FSEUFVW.mjs → chunk-RSNS5OYS.mjs} +6 -6
  98. package/dist/js/chunks/chunk-RSNS5OYS.mjs.map +7 -0
  99. package/dist/js/chunks/{chunk-ROH2HDB4.mjs → chunk-RUDYMEJ3.mjs} +2 -2
  100. package/dist/js/chunks/{chunk-BIGU5RCJ.mjs → chunk-STJR62SU.mjs} +13 -5
  101. package/dist/js/chunks/chunk-STJR62SU.mjs.map +7 -0
  102. package/dist/js/chunks/{chunk-752ADW4M.mjs → chunk-SUSD4UTN.mjs} +27 -32
  103. package/dist/js/chunks/chunk-SUSD4UTN.mjs.map +7 -0
  104. package/dist/js/chunks/{chunk-B7DQFHA5.mjs → chunk-SYBOA5HC.mjs} +7 -12
  105. package/dist/js/chunks/chunk-SYBOA5HC.mjs.map +7 -0
  106. package/dist/js/chunks/{chunk-TFABTUAZ.mjs → chunk-T4MOBP3J.mjs} +2 -2
  107. package/dist/js/chunks/{chunk-GCWWEZKO.mjs → chunk-TM7HPGTV.mjs} +3 -3
  108. package/dist/js/chunks/{chunk-5KIHWJI2.mjs → chunk-TMQDZSDC.mjs} +34 -12
  109. package/dist/js/chunks/chunk-TMQDZSDC.mjs.map +7 -0
  110. package/dist/js/chunks/{chunk-ZO6ZLHFF.mjs → chunk-TVSX5YA2.mjs} +3 -3
  111. package/dist/js/chunks/{chunk-INLZWHLY.mjs → chunk-UHO5CV6K.mjs} +2 -2
  112. package/dist/js/chunks/{chunk-INLZWHLY.mjs.map → chunk-UHO5CV6K.mjs.map} +2 -2
  113. package/dist/js/chunks/{chunk-7YQBHTK3.mjs → chunk-UKCNELUN.mjs} +6 -8
  114. package/dist/js/chunks/chunk-UKCNELUN.mjs.map +7 -0
  115. package/dist/js/chunks/{chunk-VH4BMAZS.mjs → chunk-UKQK5GWR.mjs} +13 -13
  116. package/dist/js/chunks/chunk-UKQK5GWR.mjs.map +7 -0
  117. package/dist/js/chunks/{chunk-OYNUDOHR.mjs → chunk-UTSLYQ65.mjs} +7 -6
  118. package/dist/js/chunks/{chunk-OYNUDOHR.mjs.map → chunk-UTSLYQ65.mjs.map} +2 -2
  119. package/dist/js/chunks/{chunk-7W7TV6NY.mjs → chunk-VS5OJBOD.mjs} +2 -2
  120. package/dist/js/chunks/{chunk-7W7TV6NY.mjs.map → chunk-VS5OJBOD.mjs.map} +2 -2
  121. package/dist/js/chunks/{chunk-KYIEG4U3.mjs → chunk-VZMROW5A.mjs} +43 -14
  122. package/dist/js/chunks/chunk-VZMROW5A.mjs.map +7 -0
  123. package/dist/js/chunks/{chunk-VFV75DHF.mjs → chunk-XB6Y7P5W.mjs} +11 -12
  124. package/dist/js/chunks/chunk-XB6Y7P5W.mjs.map +7 -0
  125. package/dist/js/chunks/{chunk-CZSQHXEV.mjs → chunk-XDAMOMVD.mjs} +20 -21
  126. package/dist/js/chunks/chunk-XDAMOMVD.mjs.map +7 -0
  127. package/dist/js/chunks/{chunk-EVCVFEV3.mjs → chunk-XJPMW5SP.mjs} +21 -35
  128. package/dist/js/chunks/chunk-XJPMW5SP.mjs.map +7 -0
  129. package/dist/js/chunks/{chunk-VR3L2WN5.mjs → chunk-YKANQILZ.mjs} +7 -6
  130. package/dist/js/chunks/chunk-YKANQILZ.mjs.map +7 -0
  131. package/dist/js/chunks/{chunk-JUKBBN6P.mjs → chunk-YLZOJLDI.mjs} +2 -2
  132. package/dist/js/chunks/{chunk-U4B3VHFS.mjs → chunk-ZK7YY322.mjs} +28 -21
  133. package/dist/js/chunks/chunk-ZK7YY322.mjs.map +7 -0
  134. package/dist/js/expressive.cjs +2739 -2387
  135. package/dist/js/expressive.cjs.map +4 -4
  136. package/dist/js/expressive.js +2739 -2387
  137. package/dist/js/expressive.js.map +4 -4
  138. package/dist/js/expressive.min.js +7 -7
  139. package/dist/js/expressive.min.js.map +4 -4
  140. package/dist/js/expressive.mjs +76 -75
  141. package/dist/js/expressive.mjs.map +1 -1
  142. package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
  143. package/dist/js/internal/behaviors/copy.mjs +3 -3
  144. package/dist/js/internal/behaviors/dataTables.mjs +2 -4
  145. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  146. package/dist/js/internal/behaviors/forms.mjs +2 -2
  147. package/dist/js/internal/behaviors/imageCompare.mjs +2 -2
  148. package/dist/js/internal/behaviors/lists.mjs +2 -2
  149. package/dist/js/internal/behaviors/paneResize.mjs +2 -2
  150. package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
  151. package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
  152. package/dist/js/internal/behaviors/sortable.mjs +2 -2
  153. package/dist/js/internal/behaviors/theme.mjs +2 -2
  154. package/dist/js/internal/behaviors/tour.mjs +2 -2
  155. package/dist/js/internal/behaviors/transferList.mjs +2 -2
  156. package/dist/js/internal/components/appBar.mjs +3 -3
  157. package/dist/js/internal/components/autocomplete.mjs +5 -4
  158. package/dist/js/internal/components/backToTop.mjs +3 -3
  159. package/dist/js/internal/components/barChart.mjs +5 -5
  160. package/dist/js/internal/components/buttonGroup.mjs +3 -3
  161. package/dist/js/internal/components/buttons.mjs +3 -3
  162. package/dist/js/internal/components/cards.mjs +3 -3
  163. package/dist/js/internal/components/carousel.mjs +3 -3
  164. package/dist/js/internal/components/cascader.mjs +4 -4
  165. package/dist/js/internal/components/characterCounter.mjs +3 -3
  166. package/dist/js/internal/components/chips.mjs +7 -6
  167. package/dist/js/internal/components/colorPicker.mjs +3 -3
  168. package/dist/js/internal/components/columnChart.mjs +4 -4
  169. package/dist/js/internal/components/commandPalette.mjs +3 -3
  170. package/dist/js/internal/components/confetti.mjs +3 -3
  171. package/dist/js/internal/components/currencyInput.mjs +3 -3
  172. package/dist/js/internal/components/datepicker.mjs +8 -7
  173. package/dist/js/internal/components/expandingCard.mjs +3 -3
  174. package/dist/js/internal/components/funnelChart.mjs +4 -4
  175. package/dist/js/internal/components/heatmapChart.mjs +4 -4
  176. package/dist/js/internal/components/hoverCard.mjs +3 -3
  177. package/dist/js/internal/components/index.mjs +60 -59
  178. package/dist/js/internal/components/inputMask.mjs +3 -3
  179. package/dist/js/internal/components/keypad.mjs +3 -3
  180. package/dist/js/internal/components/lightbox.mjs +3 -3
  181. package/dist/js/internal/components/lineChart.mjs +23 -7
  182. package/dist/js/internal/components/loadingOverlay.mjs +3 -3
  183. package/dist/js/internal/components/mapView.mjs +3 -3
  184. package/dist/js/internal/components/menu.mjs +3 -3
  185. package/dist/js/internal/components/menubar.mjs +4 -4
  186. package/dist/js/internal/components/messageScroller.mjs +3 -3
  187. package/dist/js/internal/components/mixedChart.mjs +5 -5
  188. package/dist/js/internal/components/navigationRail.mjs +3 -3
  189. package/dist/js/internal/components/particles.mjs +3 -3
  190. package/dist/js/internal/components/pieChart.mjs +4 -4
  191. package/dist/js/internal/components/pullToRefresh.mjs +3 -3
  192. package/dist/js/internal/components/questionnaire.mjs +3 -3
  193. package/dist/js/internal/components/radarChart.mjs +4 -4
  194. package/dist/js/internal/components/radialChart.mjs +4 -4
  195. package/dist/js/internal/components/registry.mjs +59 -58
  196. package/dist/js/internal/components/richTextEditor.mjs +3 -3
  197. package/dist/js/internal/components/sankeyChart.mjs +4 -4
  198. package/dist/js/internal/components/scatterChart.mjs +4 -4
  199. package/dist/js/internal/components/scrollspy.mjs +3 -3
  200. package/dist/js/internal/components/select.mjs +5 -4
  201. package/dist/js/internal/components/showMore.mjs +3 -3
  202. package/dist/js/internal/components/slider.mjs +3 -3
  203. package/dist/js/internal/components/snackbar.mjs +2 -2
  204. package/dist/js/internal/components/swipeActions.mjs +3 -3
  205. package/dist/js/internal/components/tabs.mjs +3 -3
  206. package/dist/js/internal/components/timepicker.mjs +5 -5
  207. package/dist/js/internal/components/tooltip.mjs +3 -3
  208. package/dist/js/internal/components/treeSelect.mjs +6 -5
  209. package/dist/js/internal/components/treemapChart.mjs +4 -4
  210. package/dist/js/internal/core/component.mjs +6 -4
  211. package/dist/js/internal/core/formControl.mjs +2 -2
  212. package/dist/js/internal/core/imageURL.mjs +7 -0
  213. package/dist/js/internal/core/imageURL.mjs.map +7 -0
  214. package/dist/js/internal/core/utils.mjs +11 -1
  215. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  216. package/dist/js/internal/plugins/modalDisplayPlugin.mjs +3 -3
  217. package/dist/js/modular.mjs +76 -75
  218. package/dist/types/behaviors/bottomSheets.d.ts +5 -3
  219. package/dist/types/behaviors/dataTables.d.ts +2 -6
  220. package/dist/types/behaviors/forms.d.ts +7 -7
  221. package/dist/types/behaviors/imageCompare.d.ts +2 -1
  222. package/dist/types/behaviors/transferList.d.ts +2 -0
  223. package/dist/types/components/autocomplete.d.ts +14 -3
  224. package/dist/types/components/carousel.d.ts +7 -0
  225. package/dist/types/components/chips.d.ts +15 -0
  226. package/dist/types/components/colorPicker.d.ts +14 -0
  227. package/dist/types/components/currencyInput.d.ts +5 -4
  228. package/dist/types/components/datepicker.d.ts +54 -27
  229. package/dist/types/components/funnelChart.d.ts +1 -4
  230. package/dist/types/components/heatmapChart.d.ts +3 -0
  231. package/dist/types/components/hoverCard.d.ts +1 -0
  232. package/dist/types/components/inputMask.d.ts +0 -2
  233. package/dist/types/components/lineChart.d.ts +43 -5
  234. package/dist/types/components/mapView.d.ts +113 -11
  235. package/dist/types/components/menu.d.ts +14 -0
  236. package/dist/types/components/particles.d.ts +14 -1
  237. package/dist/types/components/pieChart.d.ts +1 -2
  238. package/dist/types/components/richTextEditor.d.ts +40 -9
  239. package/dist/types/components/select.d.ts +1 -3
  240. package/dist/types/components/showMore.d.ts +2 -0
  241. package/dist/types/components/slider.d.ts +0 -1
  242. package/dist/types/components/snackbar.d.ts +7 -1
  243. package/dist/types/components/tabs.d.ts +3 -3
  244. package/dist/types/components/timepicker.d.ts +15 -6
  245. package/dist/types/components/tooltip.d.ts +1 -1
  246. package/dist/types/components/treemapChart.d.ts +2 -2
  247. package/dist/types/core/component.d.ts +9 -3
  248. package/dist/types/core/imageURL.d.ts +2 -0
  249. package/dist/types/core/utils.d.ts +39 -1
  250. package/dist/types/modular.d.ts +1 -1
  251. package/dist/types/plugins/modalDisplayPlugin.d.ts +8 -1
  252. package/package.json +8 -6
  253. package/src/sass/abstracts/_mixins.scss +459 -59
  254. package/src/sass/abstracts/_variables.scss +25 -0
  255. package/src/sass/components/_accordion.scss +1 -3
  256. package/src/sass/components/_aura.scss +1 -0
  257. package/src/sass/components/_back-to-top.scss +3 -3
  258. package/src/sass/components/_bar-chart.scss +2 -83
  259. package/src/sass/components/_bottom-sheet.scss +7 -0
  260. package/src/sass/components/_breadcrumb.scss +1 -7
  261. package/src/sass/components/_button-groups.scss +15 -38
  262. package/src/sass/components/_buttons.scss +24 -74
  263. package/src/sass/components/_calendar.scss +1 -3
  264. package/src/sass/components/_carousel.scss +10 -10
  265. package/src/sass/components/_cascader.scss +3 -14
  266. package/src/sass/components/_column-chart.scss +1 -19
  267. package/src/sass/components/_confetti.scss +3 -4
  268. package/src/sass/components/_data-table.scss +10 -0
  269. package/src/sass/components/_dialog.scss +10 -18
  270. package/src/sass/components/_expanding-card.scss +1 -5
  271. package/src/sass/components/_fab-menu.scss +4 -12
  272. package/src/sass/components/_funnel-chart.scss +1 -62
  273. package/src/sass/components/_heatmap-chart.scss +2 -6
  274. package/src/sass/components/_icon-buttons.scss +1 -4
  275. package/src/sass/components/_line-chart.scss +2 -70
  276. package/src/sass/components/_map.scss +4 -0
  277. package/src/sass/components/_marquee.scss +3 -3
  278. package/src/sass/components/_mega-menu.scss +8 -17
  279. package/src/sass/components/_menu.scss +10 -11
  280. package/src/sass/components/_menubar.scss +1 -13
  281. package/src/sass/components/_mixed-chart.scss +1 -37
  282. package/src/sass/components/_navbar.scss +11 -16
  283. package/src/sass/components/_navigation-bar.scss +2 -5
  284. package/src/sass/components/_navigation-rail.scss +25 -15
  285. package/src/sass/components/_page-footer.scss +1 -3
  286. package/src/sass/components/_pagination.scss +3 -14
  287. package/src/sass/components/_panes.scss +3 -16
  288. package/src/sass/components/_particles.scss +3 -4
  289. package/src/sass/components/_pie-chart.scss +8 -70
  290. package/src/sass/components/_progress.scss +31 -13
  291. package/src/sass/components/_radar-chart.scss +2 -32
  292. package/src/sass/components/_radial-chart.scss +2 -48
  293. package/src/sass/components/_sankey-chart.scss +5 -28
  294. package/src/sass/components/_scatter-chart.scss +2 -11
  295. package/src/sass/components/_search.scss +1 -4
  296. package/src/sass/components/_side-sheet.scss +9 -14
  297. package/src/sass/components/_skeleton.scss +24 -15
  298. package/src/sass/components/_snackbar.scss +11 -13
  299. package/src/sass/components/_table_of_contents.scss +1 -3
  300. package/src/sass/components/_tabs.scss +4 -20
  301. package/src/sass/components/_timepicker.scss +2 -1
  302. package/src/sass/components/_toolbar.scss +1 -4
  303. package/src/sass/components/_tooltip.scss +9 -5
  304. package/src/sass/components/_tree.scss +5 -17
  305. package/src/sass/components/_treemap-chart.scss +2 -26
  306. package/src/sass/components/forms/_checkboxes.scss +2 -21
  307. package/src/sass/components/forms/_drop-zone.scss +1 -4
  308. package/src/sass/components/forms/_fieldset.scss +1 -4
  309. package/src/sass/components/forms/_file-input.scss +6 -0
  310. package/src/sass/components/forms/_input-fields.scss +21 -4
  311. package/src/sass/components/forms/_radio-buttons.scss +2 -24
  312. package/src/sass/components/forms/_select.scss +6 -7
  313. package/src/sass/components/forms/_slider.scss +1 -4
  314. package/src/sass/components/forms/_switches.scss +14 -21
  315. package/src/sass/utilities/_helpers.scss +1 -1
  316. package/src/sass/utilities/_visibility.scss +1 -3
  317. package/dist/js/chunks/chunk-2CS6TITK.mjs.map +0 -7
  318. package/dist/js/chunks/chunk-3L3QIYLC.mjs.map +0 -7
  319. package/dist/js/chunks/chunk-4IKVPCSU.mjs +0 -7
  320. package/dist/js/chunks/chunk-4QUCNFSD.mjs.map +0 -7
  321. package/dist/js/chunks/chunk-4TRZ2AER.mjs.map +0 -7
  322. package/dist/js/chunks/chunk-5KIHWJI2.mjs.map +0 -7
  323. package/dist/js/chunks/chunk-6FSEUFVW.mjs.map +0 -7
  324. package/dist/js/chunks/chunk-752ADW4M.mjs.map +0 -7
  325. package/dist/js/chunks/chunk-7NLUI3RR.mjs.map +0 -7
  326. package/dist/js/chunks/chunk-7YQBHTK3.mjs.map +0 -7
  327. package/dist/js/chunks/chunk-7YZ5CN3V.mjs.map +0 -7
  328. package/dist/js/chunks/chunk-B7DQFHA5.mjs.map +0 -7
  329. package/dist/js/chunks/chunk-BIGU5RCJ.mjs.map +0 -7
  330. package/dist/js/chunks/chunk-BPF3I2MN.mjs.map +0 -7
  331. package/dist/js/chunks/chunk-CMGXGYUC.mjs.map +0 -7
  332. package/dist/js/chunks/chunk-CSYWKEK3.mjs.map +0 -7
  333. package/dist/js/chunks/chunk-CZSQHXEV.mjs.map +0 -7
  334. package/dist/js/chunks/chunk-DZYVU75J.mjs.map +0 -7
  335. package/dist/js/chunks/chunk-EC26RU2D.mjs.map +0 -7
  336. package/dist/js/chunks/chunk-EVCVFEV3.mjs.map +0 -7
  337. package/dist/js/chunks/chunk-FCNF4GRJ.mjs.map +0 -7
  338. package/dist/js/chunks/chunk-GWZ76SR4.mjs.map +0 -7
  339. package/dist/js/chunks/chunk-KYIEG4U3.mjs.map +0 -7
  340. package/dist/js/chunks/chunk-KZPSAXIU.mjs.map +0 -7
  341. package/dist/js/chunks/chunk-LDXCC2L3.mjs.map +0 -7
  342. package/dist/js/chunks/chunk-NBJAUGPP.mjs.map +0 -7
  343. package/dist/js/chunks/chunk-OUCHKSAW.mjs.map +0 -7
  344. package/dist/js/chunks/chunk-P6DRQ6KS.mjs.map +0 -7
  345. package/dist/js/chunks/chunk-PA7NU5AK.mjs.map +0 -7
  346. package/dist/js/chunks/chunk-QACZ6TUP.mjs.map +0 -7
  347. package/dist/js/chunks/chunk-QXKWVHBD.mjs.map +0 -7
  348. package/dist/js/chunks/chunk-S23RJ3XY.mjs.map +0 -7
  349. package/dist/js/chunks/chunk-SPPHF7YZ.mjs.map +0 -7
  350. package/dist/js/chunks/chunk-U4B3VHFS.mjs.map +0 -7
  351. package/dist/js/chunks/chunk-UGJHCHXG.mjs.map +0 -7
  352. package/dist/js/chunks/chunk-VFV75DHF.mjs.map +0 -7
  353. package/dist/js/chunks/chunk-VGY4M57S.mjs.map +0 -7
  354. package/dist/js/chunks/chunk-VH4BMAZS.mjs.map +0 -7
  355. package/dist/js/chunks/chunk-VJVQIXHC.mjs.map +0 -7
  356. package/dist/js/chunks/chunk-VMY55K2X.mjs.map +0 -7
  357. package/dist/js/chunks/chunk-VR3L2WN5.mjs.map +0 -7
  358. package/dist/js/chunks/chunk-WU7XJ4RR.mjs.map +0 -7
  359. package/dist/js/chunks/chunk-Y6TLRA3U.mjs.map +0 -7
  360. package/dist/js/chunks/chunk-Z4GICXR2.mjs.map +0 -7
  361. package/dist/js/chunks/chunk-Z4OARDZ7.mjs.map +0 -7
  362. package/dist/js/chunks/chunk-ZM3XBHWV.mjs.map +0 -7
  363. package/dist/js/chunks/chunk-ZVLOUDIJ.mjs.map +0 -7
  364. /package/dist/js/chunks/{chunk-Y6H2X7ZC.mjs.map → chunk-3KF65KGL.mjs.map} +0 -0
  365. /package/dist/js/chunks/{chunk-75E5EDJF.mjs.map → chunk-3XORNED5.mjs.map} +0 -0
  366. /package/dist/js/chunks/{chunk-NNHVANQA.mjs.map → chunk-4WBGAQN3.mjs.map} +0 -0
  367. /package/dist/js/chunks/{chunk-ZJNLAGY5.mjs.map → chunk-5F4URJHL.mjs.map} +0 -0
  368. /package/dist/js/chunks/{chunk-GVZQH2H5.mjs.map → chunk-AEG6LOAJ.mjs.map} +0 -0
  369. /package/dist/js/chunks/{chunk-AI73GJKG.mjs.map → chunk-BB5VXYXT.mjs.map} +0 -0
  370. /package/dist/js/chunks/{chunk-2RLBDFH4.mjs.map → chunk-BDATLH3H.mjs.map} +0 -0
  371. /package/dist/js/chunks/{chunk-ZKWUWBUB.mjs.map → chunk-CY2CTOVM.mjs.map} +0 -0
  372. /package/dist/js/chunks/{chunk-67ZPPKXS.mjs.map → chunk-FNIIH2LU.mjs.map} +0 -0
  373. /package/dist/js/chunks/{chunk-T3BNSRP3.mjs.map → chunk-HQRLBTNM.mjs.map} +0 -0
  374. /package/dist/js/chunks/{chunk-NAC72P7R.mjs.map → chunk-I2F7MLUU.mjs.map} +0 -0
  375. /package/dist/js/chunks/{chunk-ANKFWNWT.mjs.map → chunk-LC4O5LFS.mjs.map} +0 -0
  376. /package/dist/js/chunks/{chunk-4PIXLDNJ.mjs.map → chunk-LEF33SCP.mjs.map} +0 -0
  377. /package/dist/js/chunks/{chunk-ILDRRG7T.mjs.map → chunk-LFORZRPH.mjs.map} +0 -0
  378. /package/dist/js/chunks/{chunk-4EWGD4V2.mjs.map → chunk-NODZ5VAD.mjs.map} +0 -0
  379. /package/dist/js/chunks/{chunk-NVQ5EHCU.mjs.map → chunk-QNODAANY.mjs.map} +0 -0
  380. /package/dist/js/chunks/{chunk-ROH2HDB4.mjs.map → chunk-RUDYMEJ3.mjs.map} +0 -0
  381. /package/dist/js/chunks/{chunk-TFABTUAZ.mjs.map → chunk-T4MOBP3J.mjs.map} +0 -0
  382. /package/dist/js/chunks/{chunk-GCWWEZKO.mjs.map → chunk-TM7HPGTV.mjs.map} +0 -0
  383. /package/dist/js/chunks/{chunk-ZO6ZLHFF.mjs.map → chunk-TVSX5YA2.mjs.map} +0 -0
  384. /package/dist/js/chunks/{chunk-JUKBBN6P.mjs.map → chunk-YLZOJLDI.mjs.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/questionnaire.ts"],
4
- "sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\nexport interface QuestionnaireOptions extends BaseOptions {\n /**\n * Text above the progress bar. `{current}` and `{total}` are replaced with\n * the question number and the number of questions. `data-progress-label`\n * on the form sets it.\n * @default 'Question {current} of {total}'\n */\n progressLabel: string;\n /**\n * Error shown when a question has no `.questionnaire-error` of its own and\n * the browser gives no validation message, as for a `data-required` group\n * of checkboxes.\n * @default 'Choose an answer to continue.'\n */\n requiredMessage: string;\n /**\n * With `data-summary`, the heading of the review step and the text above\n * the progress bar there.\n * @default 'Review your answers'\n */\n summaryLabel: string;\n /** With `data-summary`, the text of each answer's edit button. @default 'Edit' */\n editLabel: string;\n /** With `data-summary`, the answer shown for a question left blank. @default 'Not answered' */\n skippedLabel: string;\n}\n\nconst _defaults: QuestionnaireOptions = {\n progressLabel: 'Question {current} of {total}',\n requiredMessage: 'Choose an answer to continue.',\n summaryLabel: 'Review your answers',\n editLabel: 'Edit',\n skippedLabel: 'Not answered'\n};\n\nconst NAVIGATION = ['previous', 'skip', 'next'];\nconst UNSAVED = ['file', 'password', 'hidden'];\nconst LETTERS = 'abcdefghijklmnopqrstuvwxyz';\n\ntype Control = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n/** A control's answer as saved: whether a choice is checked, a select's chosen values, or a field's value. */\ntype Saved = boolean | string | string[];\n\nconst isChoice = (control: Control): control is HTMLInputElement =>\n control instanceof HTMLInputElement && (control.type === 'radio' || control.type === 'checkbox');\n\n/** A choice's label text, without its input or the description in <small>. */\nfunction labelText(control: HTMLInputElement) {\n const label = control.closest('label')?.cloneNode(true) as HTMLElement | undefined;\n label?.querySelectorAll('input, small').forEach((el) => el.remove());\n return label?.textContent.trim() || control.value;\n}\n\n/** A control's answer as text for the summary. */\nfunction answerText(control: Control) {\n if (control instanceof HTMLSelectElement) return Array.from(control.selectedOptions, (option) => option.text).join(', ');\n if (isChoice(control)) return control.checked ? labelText(control) : '';\n return control.value.trim();\n}\n\nconst savedState = (control: Control): Saved => {\n if (control instanceof HTMLSelectElement) return Array.from(control.selectedOptions, (option) => option.value);\n return isChoice(control) ? control.checked : control.value;\n};\n\n/** Saved state with a list of answers, or null. */\nconst validSaved = (saved: { answers?: unknown } | null) =>\n (Array.isArray(saved?.answers) ? saved : null) as { index: number; answers: Saved[] } | null;\n\n/** Puts a saved answer back, ignoring one of the wrong type, as a hand-edited store may hold. */\nfunction restoreState(control: Control, saved: Saved) {\n if (control instanceof HTMLSelectElement) return restoreSelect(control, saved);\n if (isChoice(control)) control.checked = saved === true;\n else if (typeof saved === 'string') control.value = saved;\n}\n\nfunction restoreSelect(select: HTMLSelectElement, saved: Saved) {\n if (!Array.isArray(saved)) return;\n for (const option of select.options) option.selected = saved.includes(option.value);\n}\n\n/**\n * Restores one control and fires `change` if its answer moved, so a page\n * that switches questions on from an answer sees the restored one.\n */\nfunction restoreControl(control: Control, saved: Saved) {\n const before = JSON.stringify(savedState(control));\n restoreState(control, saved);\n if (JSON.stringify(savedState(control)) !== before) control.dispatchEvent(new Event('change', { bubbles: true }));\n}\n\n/**\n * The answer a shortcut key picks, counted from 0: a digit 1 to 9 or a\n * letter. Keys typed into a text field, or with a modifier, pick nothing.\n */\nfunction shortcut(e: KeyboardEvent) {\n if (typingIn(e.target) || !Utils.plainKey(e)) return -1;\n const digit = '123456789'.indexOf(e.key);\n return digit >= 0 ? digit : letterIndex(e.key);\n}\n\nconst TYPING = 'textarea, select, [contenteditable], input:not([type=\"radio\"], [type=\"checkbox\"], [type=\"button\"], [type=\"submit\"], [type=\"reset\"])';\nconst typingIn = (target: EventTarget | null) => !!(target as Element).matches?.(TYPING);\n\nconst letterIndex = (key: string) => (key.length === 1 ? LETTERS.indexOf(key.toLowerCase()) : -1);\n\n/**\n * A multi-step questionnaire: a <form class=\"questionnaire\"> whose\n * <fieldset> children are the questions, shown one at a time, and a <footer>\n * of buttons. `value=\"previous\"`, `value=\"skip\"` and `value=\"next\"` mark the\n * navigation buttons; a submit button sends the form on the last question.\n *\n * A question is required when one of its controls is `required`, or when the\n * fieldset has `data-required` (at least one enabled checkbox, held as a\n * custom validity on the first one). Next and every way of submitting check\n * it with the browser's own validation; an optional question gets Skip, which\n * clears its answer. A disabled fieldset is left out, so a page can switch\n * questions on and off from earlier answers.\n *\n * Three attributes on the form add to that: `data-shortcuts` lets a letter or\n * digit pick an answer, `data-summary` adds a review step listing every\n * answer before the submit button, and `data-save=\"key\"` keeps the answers\n * and the shown question in localStorage under that key until the form is\n * submitted.\n *\n * Without JavaScript every question shows at once and the submit button sends\n * the form. The answers are ordinary form controls, so FormData reads them.\n */\nexport class Questionnaire extends Component<QuestionnaireOptions> {\n declare el: HTMLFormElement;\n private _active: HTMLFieldSetElement | null = null;\n private _progress: HTMLElement;\n private _progressText: HTMLElement;\n private _progressBar: HTMLProgressElement;\n private _generated: HTMLElement[] = [];\n private _generatedIds: HTMLElement[] = [];\n private _observer: MutationObserver;\n /** Set while one submission's invalid events arrive, so only the first opens. */\n private _reporting = false;\n /** With data-summary, the review step, and whether it is shown. */\n private _summary: HTMLElement | null = null;\n private _reviewing = false;\n\n // HTMLElement, not HTMLFormElement: init() takes the element type from\n // here, and has always accepted any HTMLElement.\n constructor(el: HTMLElement, options: Partial<QuestionnaireOptions>) {\n const progressLabel = el.dataset.progressLabel;\n super(el, { ...(progressLabel ? { progressLabel } : {}), ...options });\n\n this._progress = document.createElement('div');\n this._progress.className = 'questionnaire-progress';\n this._progressText = document.createElement('span');\n this._progressText.id = `questionnaire-progress-${Utils.guid()}`;\n this._progressBar = document.createElement('progress');\n this._progressBar.className = 'progress';\n this._progressBar.setAttribute('aria-labelledby', this._progressText.id);\n this._progress.append(this._progressText, this._progressBar);\n this.el.prepend(this._progress);\n\n for (const item of this._fieldsets()) {\n const ids = Array.from(item.querySelectorAll<HTMLElement>(':scope > p:not(.questionnaire-error)'))\n .map((p) => this._ensureId(p, 'questionnaire-description'));\n if (ids.length && !item.hasAttribute('aria-describedby')) {\n item.setAttribute('aria-describedby', ids.join(' '));\n this._generatedIds.push(item);\n }\n }\n\n this._active = this.items[0] ?? null;\n this._summary = this._createSummary();\n this._restore();\n this._syncRequired();\n this._render();\n // A page enabling or disabling a question from an earlier answer changes\n // the count and the buttons.\n this._observer = new MutationObserver(() => {\n this._syncRequired();\n this._render();\n });\n this._observer.observe(this.el, { attributes: true, subtree: true, attributeFilter: ['disabled'] });\n const { signal } = this._events;\n this.el.addEventListener('click', this._handleClick, { signal });\n this.el.addEventListener('keydown', this._handleKeydown, { signal });\n this.el.addEventListener('input', this._handleInput, { signal });\n this.el.addEventListener('change', this._save, { signal });\n this.el.addEventListener('submit', this._forget, { signal });\n // invalid does not bubble.\n this.el.addEventListener('invalid', this._handleInvalid, { capture: true, signal });\n }\n\n static get defaults(): QuestionnaireOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Questionnaire';\n\n /** The questions that apply: every fieldset child that is not disabled. */\n get items(): HTMLFieldSetElement[] {\n return this._fieldsets().filter((item) => !item.disabled);\n }\n\n /** Position of the shown question in `items`. */\n get index(): number {\n return this.items.indexOf(this._active);\n }\n\n /** Shows the question at `index` without checking the current one. */\n goTo = (index: number) => {\n const item = this.items[index];\n if (!item) return;\n this._active = item;\n this._reviewing = false;\n this._render();\n this._save();\n const controls = this._controls(item).filter((control) => !control.disabled);\n (controls.find((control) => (control as HTMLInputElement).checked) ?? controls[0])?.focus();\n };\n\n /** Checks the shown question and moves to the next one if it is answered. */\n next = () => {\n if (this._validate(this._active)) this._advance();\n };\n\n /** Moves to the previous question, or from the review step back to the last one. */\n previous = () => this.goTo(this._reviewing ? this.items.length - 1 : this.index - 1);\n\n /** Shows the review step of a questionnaire with data-summary. */\n review = () => {\n if (!this._summary) return;\n this._fillSummary(this._summary);\n this._reviewing = true;\n this._render();\n this._summary.focus();\n };\n\n /** The next question, or after the last one the review step. */\n private _advance() {\n if (this._summary && this.index === this.items.length - 1) this.review();\n else this.goTo(this.index + 1);\n }\n\n /** Clears the answer to the shown question and moves to the next one. */\n skip = () => {\n if (!this._active) return;\n for (const control of this._controls(this._active)) {\n const choice = isChoice(control);\n if (choice ? !control.checked : !control.value) continue;\n if (choice) control.checked = false;\n else control.value = '';\n control.dispatchEvent(new Event('change', { bubbles: true }));\n }\n // A skipped question has no answer left to be wrong about. Clearing fires\n // only `change`, not the `input` that clears an error, so clear it here.\n this._setInvalid(this._active, false);\n this._advance();\n };\n\n destroy() {\n this._observer.disconnect();\n this._summary?.remove();\n for (const item of this._fieldsets()) {\n if (item.hasAttribute('data-required')) for (const control of this._controls(item)) control.setCustomValidity('');\n item.hidden = false;\n this._setInvalid(item, false);\n }\n for (const button of this._buttons()) button.hidden = false;\n this._progress.remove();\n for (const el of this._generated) el.remove();\n for (const el of this._generatedIds) {\n el.removeAttribute(el instanceof HTMLFieldSetElement ? 'aria-describedby' : 'id');\n }\n super.destroy();\n }\n\n private _fieldsets() {\n return Array.from(this.el.querySelectorAll<HTMLFieldSetElement>(':scope > fieldset'));\n }\n\n /** The footer's navigation and submit buttons. */\n private _buttons() {\n return Array.from(this.el.querySelectorAll<HTMLButtonElement>(':scope > footer > button')).filter(\n (button) => NAVIGATION.includes(button.value) || button.type === 'submit'\n );\n }\n\n private _controls(item: HTMLFieldSetElement) {\n return Array.from(item.elements).filter(\n (el): el is Control =>\n el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement ||\n (el instanceof HTMLInputElement && el.type !== 'button' && el.type !== 'submit')\n );\n }\n\n private _required(item: HTMLFieldSetElement) {\n return item.hasAttribute('data-required') || this._controls(item).some((control) => control.required);\n }\n\n private _ensureId(el: HTMLElement, prefix: string) {\n if (!el.id) {\n el.id = `${prefix}-${Utils.guid()}`;\n this._generatedIds.push(el);\n }\n return el.id;\n }\n\n private _render() {\n const items = this.items;\n // The shown question was switched off: carry on from the next one.\n if (!items.includes(this._active)) this._active = this._after(items);\n const index = items.indexOf(this._active);\n for (const item of this._fieldsets()) item.hidden = this._reviewing || item !== this._active;\n this._summary?.toggleAttribute('hidden', !this._reviewing);\n for (const button of this._buttons()) button.hidden = !this._shows(button, index);\n this._renderProgress(index, items.length);\n }\n\n /** The question after the shown one, which was switched off, or the last that applies. */\n private _after(items: HTMLFieldSetElement[]) {\n const all = this._fieldsets();\n const after = all.slice(all.indexOf(this._active) + 1).find((item) => !item.disabled);\n return after ?? items[items.length - 1] ?? null;\n }\n\n /** Whether the shown step is the one that submits: the review step, or without one the last question. */\n private get _end() {\n return this._summary ? this._reviewing : this.index === this.items.length - 1;\n }\n\n /** Whether a footer button applies to the shown step. */\n private _shows(button: HTMLButtonElement, index: number) {\n const end = this._end;\n const shown: Record<string, boolean> = {\n previous: index > 0 || this._reviewing,\n skip: !end && this._skippable(),\n next: !end\n };\n return shown[button.value] ?? end;\n }\n\n /** Whether the shown question may be skipped: it applies and needs no answer. */\n private _skippable() {\n return !!this._active && !this._required(this._active);\n }\n\n private _renderProgress(index: number, total: number) {\n this._progressText.textContent = this._reviewing\n ? this.options.summaryLabel\n : this.options.progressLabel.replace('{current}', String(index + 1)).replace('{total}', String(total));\n this._progressBar.max = Math.max(total, 1);\n this._progressBar.value = this._reviewing ? total : index + 1;\n }\n\n /** With data-summary, the review step: a list of the questions and their answers, before the footer. */\n private _createSummary() {\n if (!this.el.hasAttribute('data-summary')) return null;\n const summary = document.createElement('section');\n summary.className = 'questionnaire-summary';\n summary.tabIndex = -1;\n summary.setAttribute('aria-label', this.options.summaryLabel);\n summary.hidden = true;\n summary.addEventListener('click', (e) => {\n const edit = (e.target as Element).closest<HTMLButtonElement>('button[data-question]');\n if (edit) this.goTo(Number(edit.dataset.question));\n });\n const footer = this.el.querySelector(':scope > footer');\n if (footer) footer.before(summary);\n else this.el.append(summary);\n return summary;\n }\n\n /** Lists each question that applies with its answer and a button back to it. */\n private _fillSummary(summary: HTMLElement) {\n const list = document.createElement('dl');\n list.append(...this.items.map((item, i) => {\n const row = document.createElement('div');\n const [term, answer, action] = [document.createElement('dt'), document.createElement('dd'), document.createElement('dd')];\n term.id = `questionnaire-summary-${Utils.guid()}`;\n term.textContent = item.querySelector(':scope > legend')?.textContent.trim() ?? '';\n answer.textContent = this._controls(item).map(answerText).filter(Boolean).join(', ') || this.options.skippedLabel;\n const edit = document.createElement('button');\n Object.assign(edit, { type: 'button', className: 'text', textContent: this.options.editLabel });\n edit.dataset.question = String(i);\n edit.setAttribute('aria-describedby', term.id);\n action.append(edit);\n row.append(term, answer, action);\n return row;\n }));\n summary.replaceChildren(list);\n }\n\n /** The storage key from data-save, or '' without it. */\n private get _key() {\n const key = this.el.dataset.save;\n return key ? `questionnaire:${key}` : '';\n }\n\n /**\n * Every answer control that can be saved, in order. A file cannot be put back,\n * a password must not sit in storage, and a hidden input is the server's.\n */\n private _allControls() {\n return this._fieldsets().flatMap((item) => this._controls(item)).filter((control) => !UNSAVED.includes(control.type));\n }\n\n /** With data-save, stores the answers and the shown question. */\n private _save = () => {\n const key = this._key;\n if (!key) return;\n const state = { index: this.index, answers: this._allControls().map(savedState) };\n try {\n localStorage.setItem(key, JSON.stringify(state));\n } catch {\n // Storage full or blocked: the questionnaire still works unsaved.\n }\n };\n\n /** Puts back saved answers and the question they reached, if the questions are the same. */\n private _restore() {\n const saved = this._read();\n const controls = this._allControls();\n if (saved?.answers.length !== controls.length) return;\n controls.forEach((control, i) => restoreControl(control, saved!.answers[i]));\n this._active = this.items[saved!.index] ?? this._active;\n }\n\n /** The saved state, or null for none or a broken one. */\n private _read(): { index: number; answers: Saved[] } | null {\n try {\n return validSaved(JSON.parse(localStorage.getItem(this._key) ?? 'null'));\n } catch {\n return null;\n }\n }\n\n /** A submitted questionnaire has nothing left to resume. */\n private _forget = () => {\n try {\n if (this._key) localStorage.removeItem(this._key);\n } catch {\n // Blocked storage has nothing saved.\n }\n };\n\n /**\n * Puts \"choose at least one\" on the first enabled checkbox of each\n * data-required group with none checked, so the browser's validation, and\n * every way of submitting, sees it. A disabled checkbox is not sent, so it\n * does not count.\n */\n private _syncRequired() {\n for (const item of this._fieldsets()) {\n if (!item.hasAttribute('data-required')) continue;\n const boxes = this._controls(item).filter(\n (control): control is HTMLInputElement => control instanceof HTMLInputElement && control.type === 'checkbox'\n );\n const enabled = boxes.filter((box) => !box.disabled);\n for (const box of boxes) box.setCustomValidity('');\n if (enabled.length && !enabled.some((box) => box.checked)) {\n const error = item.querySelector<HTMLElement>(':scope > .questionnaire-error:not([data-generated])');\n enabled[0].setCustomValidity(error?.textContent.trim() || this.options.requiredMessage);\n }\n }\n }\n\n /** The first control in the question that still needs an answer. */\n private _invalidControl(item: HTMLFieldSetElement): Control | undefined {\n return this._controls(item).find((control) => control.willValidate && !control.validity.valid);\n }\n\n /** Shows the question's error and returns false when it needs an answer. */\n private _validate(item: HTMLFieldSetElement | null) {\n this._syncRequired();\n const invalid = item && this._invalidControl(item);\n if (!invalid) return true;\n let error = item.querySelector<HTMLElement>(':scope > .questionnaire-error');\n if (!error) {\n error = document.createElement('p');\n error.className = 'questionnaire-error';\n error.dataset.generated = '';\n error.textContent = invalid.validationMessage || this.options.requiredMessage;\n item.append(error);\n this._generated.push(error);\n }\n this._setInvalid(item, true);\n invalid.focus();\n return false;\n }\n\n private _setInvalid(item: HTMLFieldSetElement, invalid: boolean) {\n item.classList.toggle('invalid', invalid);\n const error = item.querySelector<HTMLElement>(':scope > .questionnaire-error');\n const described = (item.getAttribute('aria-describedby') ?? '').split(' ').filter((id) => id && id !== error?.id);\n if (invalid && error) described.push(this._ensureId(error, 'questionnaire-error'));\n if (described.length) item.setAttribute('aria-describedby', described.join(' '));\n else item.removeAttribute('aria-describedby');\n for (const control of this._controls(item)) {\n if (invalid) control.setAttribute('aria-invalid', 'true');\n else control.removeAttribute('aria-invalid');\n }\n if (!invalid && this._generated.includes(error)) {\n error.remove();\n this._generated.splice(this._generated.indexOf(error), 1);\n }\n }\n\n private _handleClick = (e: MouseEvent) => {\n const button = (e.target as Element).closest?.('button');\n if (!button || !this._buttons().includes(button)) return;\n if (NAVIGATION.includes(button.value)) {\n // Also stops a navigation button written without type=\"button\" from\n // submitting the form.\n e.preventDefault();\n this[button.value as 'previous' | 'skip' | 'next']();\n return;\n }\n // Submit by click or Enter: catch answers a script set without an event.\n this._syncRequired();\n };\n\n // Enter in a field moves on instead of submitting the form early. With\n // data-shortcuts, a letter or digit picks an answer.\n private _handleKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Enter') return this._handleShortcut(e);\n if (e.defaultPrevented || Utils.isComposing(e)) return;\n if (!(e.target instanceof HTMLInputElement) || this._end) return;\n e.preventDefault();\n this.next();\n };\n\n /** Whether a shortcut key can pick an answer now: data-shortcuts is set and a question shows. */\n private get _shortcuts() {\n return this.el.hasAttribute('data-shortcuts') && !!this._active && !this._reviewing;\n }\n\n private _handleShortcut(e: KeyboardEvent) {\n if (!this._shortcuts) return;\n // Counted as the letters are, disabled choices included.\n const choice = this._controls(this._active!).filter(isChoice)[shortcut(e)] as HTMLInputElement | undefined;\n if (!choice || choice.disabled) return;\n e.preventDefault();\n choice.click();\n choice.focus();\n }\n\n // A submission found an unanswered question, possibly a hidden one. Open the\n // first instead of letting the browser report a control it cannot show.\n // One submission fires its invalid events in a single task.\n private _handleInvalid = (e: Event) => {\n const item = this.items.find((item) => item.contains(e.target as Node));\n if (!item) return;\n e.preventDefault();\n if (this._reporting) return;\n this._reporting = true;\n setTimeout(() => (this._reporting = false));\n this._active = item;\n this._reviewing = false;\n this._render();\n this._validate(item);\n };\n\n // An answer clears the question's error.\n private _handleInput = (e: Event) => {\n this._syncRequired();\n this._save();\n const item = (e.target as Element).closest?.('fieldset');\n if (item instanceof HTMLFieldSetElement && item.classList.contains('invalid')) this._setInvalid(item, false);\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["item"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/timepicker.ts"],
4
- "sourcesContent": ["import { Utils, controllerFor, pickerFooter, svgNode } from '../core/utils';\nimport { Component, BaseOptions, I18nOptions } from '../core/component';\nimport { DisplayPlugin, createDisplayPlugin, hideModal } from '../plugins/modalDisplayPlugin';\n\nexport type Views = 'hours' | 'minutes';\n\n/** The clock's fields, in the order they appear. */\nconst UNITS = ['hours', 'minutes', 'seconds'] as const;\ntype Unit = (typeof UNITS)[number];\n\n/** How far each key moves a field, wrapping round. */\nconst STEPS: Record<string, number> = { ArrowUp: 1, ArrowDown: -1, PageUp: 5, PageDown: -5 };\n\n/** A 12-hour time's hour of the day, 0 to 23. */\nconst dayHour = (hours: number, pm: boolean) => (hours % 12) + (pm ? 12 : 0);\n\n/** Each field's length in seconds and how many values it has. */\nconst SPANS: Record<Unit, [number, number]> = { hours: [3600, 24], minutes: [60, 60], seconds: [1, 60] };\n\n/**\n * The hour at a position on the 24-hour dial, 0 to 12 from the top: the\n * inner ring holds 1 to 12, the outer 13 to 23 and 00.\n */\nconst ringHour = (position: number, inner: boolean) => {\n const hour = (position % 12) + (inner ? 0 : 12);\n return hour % 12 ? hour : 12 - hour;\n};\n\n/** The last second of the day. */\nconst DAY_END = 24 * 3600 - 1;\n\n/** A clock number as two digits. */\nconst pad2 = (n: number) => String(n).padStart(2, '0');\n\n/**\n * The hour on the 24-hour clock, minute and second of a written time such as\n * '14:30', '02:30:45 PM' or 'now'. A missing part reads as 0.\n */\nfunction readTime(text: string, fromNow: number): [number, number, number] {\n const upper = text.trim().toUpperCase();\n if (upper.split(':')[0] === 'NOW') {\n const now = new Date(+new Date() + fromNow);\n return [now.getHours(), now.getMinutes(), now.getSeconds()];\n }\n const period = /AM|PM/.exec(upper)?.[0];\n const parts = upper.replace(/AM|PM/, '').split(':');\n const [hours, minutes, seconds] = [0, 1, 2].map((i) => +parts[i] || 0);\n // A written AM or PM fixes the hour on either clock: \"03:30 PM\" is 15:30\n // on a 24-hour clock too.\n return [period ? dayHour(hours, period === 'PM') : hours, minutes, seconds];\n}\n\n/** Seconds since midnight for an hour, minute and second. */\nconst daySeconds = ([hours, minutes, seconds]: number[]) => hours * 3600 + minutes * 60 + seconds;\n\n/**\n * With a `lang` on or around the input, whether that language tells the\n * time on a 12-hour clock.\n */\nfunction localeClock(el: Element): Partial<TimepickerOptions> {\n const locale = Utils.locale(el);\n if (!locale) return {};\n const cycle = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hourCycle;\n return { twelveHour: cycle === 'h11' || cycle === 'h12' };\n}\n\nexport interface TimepickerOptions extends BaseOptions {\n /**\n * Dial radius.\n * @default 135\n */\n dialRadius: number;\n /**\n * Outer radius.\n * @default 105\n */\n outerRadius: number;\n /**\n * Inner radius.\n * @default 70\n */\n innerRadius: number;\n /**\n * Tick radius.\n * @default 20\n */\n tickRadius: number;\n /**\n * Duration of the transition from/to the hours/minutes view.\n * @default 350\n */\n duration: number;\n /**\n * Specify a DOM element OR selector for a DOM element to render\n * the time picker in, by default it will be placed before the input.\n * @default null\n */\n container: HTMLElement | string | null;\n /**\n * Show the clear button in the Timepicker.\n * @default false\n */\n showClearBtn: boolean;\n /**\n * Autosubmit timepicker selection to input field\n * @default true\n */\n autoSubmit: boolean;\n /**\n * Default time to set on the timepicker 'now' or '13:14'.\n * @default 'now';\n */\n defaultTime: string;\n /**\n * Millisecond offset from the defaultTime.\n * @default 0\n */\n fromNow: number;\n /**\n * Internationalization options.\n */\n i18n: Partial<I18nOptions & { hours: string; minutes: string; seconds: string }>;\n /**\n * Use 12 hour AM/PM clock instead of 24 hour clock.\n * @default true, or the clock the input's `lang` uses\n */\n twelveHour: boolean;\n /**\n * Add a seconds field after the minutes, and write `HH:MM:SS`. The dial\n * still sets hours and minutes only.\n * @default false\n */\n showSeconds: boolean;\n /**\n * The earliest time a person can choose, as 24-hour `'HH:MM'` or\n * `'HH:MM:SS'`. Without `showSeconds` it rounds up to a whole minute.\n * @default null\n */\n minTime: string | null;\n /**\n * The latest time a person can choose, as 24-hour `'HH:MM'` or\n * `'HH:MM:SS'`. Without `showSeconds` it rounds down to a whole minute.\n * @default null\n */\n maxTime: string | null;\n /**\n * Vibrate device when dragging clock hand.\n * @default true\n */\n vibrate: boolean;\n /**\n * Callback function when a time is selected.\n * @default null\n */\n onSelect: (hour: number, minute: number) => void;\n /**\n * Callback function for interaction with input field.\n * @default null\n */\n onInputInteraction: (() => void) | null;\n /**\n * Callback function for done.\n * @default null\n */\n onDone: (() => void) | null;\n /**\n * Callback function for cancel.\n * @default null\n */\n onCancel: (() => void) | null;\n /**\n * Display plugin: 'docked' for a popover under the input, or 'modal' for a\n * dialog with Cancel and Ok. A modal picker writes the input only on Ok,\n * so it clears `autoSubmit`.\n */\n displayPlugin: string;\n /**\n * Configurable display plugin options\n */\n displayPluginOptions: object;\n}\n\nconst _defaults: TimepickerOptions = {\n dialRadius: 135,\n outerRadius: 105,\n innerRadius: 70,\n tickRadius: 20,\n duration: 350,\n container: null,\n defaultTime: 'now', // default time, 'now' or '13:14' e.g.\n fromNow: 0, // Millisecond offset from the defaultTime\n showClearBtn: false,\n autoSubmit: true,\n // internationalization\n i18n: {\n cancel: 'Cancel',\n clear: 'Clear',\n done: 'Ok',\n hours: 'Hours',\n minutes: 'Minutes',\n seconds: 'Seconds'\n },\n twelveHour: true, // change to 12 hour AM/PM clock from 24 hour\n showSeconds: false,\n minTime: null,\n maxTime: null,\n vibrate: true, // vibrate the device when dragging clock hand\n // Callbacks\n onSelect: null,\n onInputInteraction: null,\n onDone: null,\n onCancel: null,\n displayPlugin: null,\n displayPluginOptions: null,\n};\n\nexport class Timepicker extends Component<TimepickerOptions> {\n declare el: HTMLInputElement;\n id: string;\n containerEl: HTMLElement;\n plate: HTMLElement;\n digitalClock: HTMLElement;\n inputHours: HTMLInputElement;\n inputMinutes: HTMLInputElement;\n /** The seconds field, or null without `showSeconds`. */\n inputSeconds: HTMLInputElement | null;\n x0: number;\n y0: number;\n moved: boolean;\n /** Which pointer is dragging the clock hand; a second finger is ignored. */\n private _dragPointerId: number | null = null;\n /** Removes the document listeners of the drag in progress. */\n private _drag: AbortController | null = null;\n dx: number;\n dy: number;\n /**\n * Current view on the timepicker.\n * @default 'hours'\n */\n currentView: Views;\n hand: SVGElement;\n minutesView: HTMLElement;\n hours: number;\n minutes: number;\n seconds: number;\n /** The selected time. */\n time: string;\n /**\n * If the time is AM or PM on twelve-hour clock.\n * @default 'PM'\n */\n amOrPm: 'AM' | 'PM';\n static _template;\n /** Whether this device exposes the Vibration API at all. */\n canVibrate: boolean;\n _canvas: HTMLElement;\n hoursView: HTMLElement;\n spanAmPm: HTMLSpanElement;\n footer: HTMLElement;\n private _amBtn: HTMLButtonElement;\n private _pmBtn: HTMLButtonElement;\n bg: Element;\n g: Element;\n toggleViewTimer: ReturnType<typeof setTimeout>;\n vibrateTimer: ReturnType<typeof setTimeout>;\n private _autoSubmitTimer: ReturnType<typeof setTimeout>;\n private _clockResetTimer: ReturnType<typeof setTimeout>;\n private displayPlugin: DisplayPlugin;\n /** Whether the dial (ticks + SVG + AM/PM buttons) has been built yet. */\n private _clockBuilt = false;\n /** Whether the pointer last pointed at a value outside the range. */\n private _handRefused = false;\n /** The first and last allowed second of the day. */\n private _limits: [number, number] = [0, DAY_END];\n\n constructor(el: HTMLInputElement, options: Partial<TimepickerOptions>) {\n super(el, { ...localeClock(el), ...options });\n // A modal clock writes on Ok, so it has the buttons.\n this.options.autoSubmit &&= this.options.displayPlugin !== 'modal';\n this.id = Utils.guid();\n this._readLimits();\n this._insertHTMLIntoDOM();\n this._setupVariables();\n this._setupEventHandlers();\n // The dial is ~40 elements (12 or 24 hour ticks, 12 minute ticks, the SVG\n // hand and the AM/PM buttons) and is built by _ensureClockBuilt() rather\n // than here - see _pickerSetup for when that first happens.\n this._pickerSetup();\n\n this.displayPlugin = createDisplayPlugin(this.options.displayPlugin, this.el, this.containerEl, this.options.displayPluginOptions, this.cancel);\n }\n\n static get defaults(): TimepickerOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Timepicker';\n\n destroy() {\n clearTimeout(this._autoSubmitTimer);\n clearTimeout(this.toggleViewTimer);\n clearTimeout(this.vibrateTimer);\n this._cancelClockReset();\n // Drag handlers live on the document while the clock hand is held; if the\n // component is destroyed mid-drag they would otherwise outlive it.\n this._drag?.abort();\n this.displayPlugin?.destroy();\n this.containerEl.remove();\n super.destroy();\n }\n\n _setupEventHandlers() {\n const { signal } = this._events;\n this.el.addEventListener('click', this._handleInputClick, { signal });\n this.el.addEventListener('keydown', this._handleInputKeydown, { signal });\n this.plate.addEventListener('pointerdown', this._handleClockClickStart);\n this.digitalClock.addEventListener('input', this._inputFromTextField, { signal });\n this.digitalClock.addEventListener('keydown', this._handleDigitalKeydown, { signal });\n this.inputHours.addEventListener('focus', () => this.showView('hours'));\n this.inputHours.addEventListener('focusout', () => this.formatHours());\n this.inputMinutes.addEventListener('focus', () => this.showView('minutes'));\n this.inputMinutes.addEventListener('focusout', () => this.formatMinutes());\n this.inputSeconds?.addEventListener('focusout', () => this.formatSeconds());\n }\n\n _handleInputClick = () => {\n this._updateTimeFromInput();\n // Before focus(): focusing inputHours fires the handler that calls\n // showView, and an already-focused input fires nothing at all.\n this._ensureClockBuilt();\n if (this.displayPlugin) this.displayPlugin.show();\n this.inputHours.focus();\n if (typeof this.options.onInputInteraction === 'function') this.options.onInputInteraction.call(this);\n };\n\n _handleInputKeydown = Utils.ignoringComposition((e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n this._handleInputClick();\n }\n });\n\n _handleClockClickStart = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n e.preventDefault();\n this._ensureClockBuilt();\n const clockPlateBR = this.plate.getBoundingClientRect();\n const offset = { x: clockPlateBR.left, y: clockPlateBR.top };\n\n this.x0 = offset.x + this.options.dialRadius;\n this.y0 = offset.y + this.options.dialRadius;\n this.moved = false;\n this._dragPointerId = e.pointerId;\n this.dx = e.clientX - this.x0;\n this.dy = e.clientY - this.y0;\n\n // Set clock hands\n this.setHand(this.dx, this.dy, false);\n // The hand follows the pointer anywhere on the page while it is held.\n // `pointercancel` ends the drag the same way `pointerup` does: without it\n // these document listeners outlived a cancelled touch, because the\n // `touchend` pair this replaced had no `touchcancel` companion.\n this._drag?.abort();\n this._drag = controllerFor(this.el);\n const { signal } = this._drag;\n document.addEventListener('pointermove', this._handleDocumentClickMove, { signal });\n document.addEventListener('pointerup', this._handleDocumentClickEnd, { signal });\n document.addEventListener('pointercancel', this._handleDocumentClickCancel, { signal });\n };\n\n _handleDocumentClickMove = (e: PointerEvent) => {\n if (e.pointerId !== this._dragPointerId) return;\n e.preventDefault();\n const x = e.clientX - this.x0;\n const y = e.clientY - this.y0;\n this.moved = true;\n this.setHand(x, y, false);\n };\n\n _handleDocumentClickEnd = (e: PointerEvent) => {\n if (e.pointerId !== this._dragPointerId) return;\n this._dragPointerId = null;\n e.preventDefault();\n this._drag.abort();\n const x = e.clientX - this.x0;\n const y = e.clientY - this.y0;\n if (this.moved && x === this.dx && y === this.dy) {\n this.setHand(x, y);\n }\n // A release on a disabled tick is no choice at all.\n if (!this._handRefused) this._chooseHand();\n };\n\n /** Take the value under the hand: move on to the minutes, or submit. */\n private _chooseHand() {\n if (this.currentView === 'hours') {\n this.inputMinutes.focus();\n this.showView('minutes', this.options.duration / 2);\n } else {\n clearTimeout(this._autoSubmitTimer);\n this._autoSubmitTimer = setTimeout(() => {\n this._autoSubmitTimer = null;\n if (this.options.autoSubmit) this.done();\n }, this.options.duration / 2);\n }\n\n const { hours, minutes } = this;\n this._notify('select', this.options.onSelect, { args: [hours, minutes], detail: { hours, minutes }, current: () => this.hours === hours && this.minutes === minutes });\n }\n\n /**\n * A cancelled pointer is not a completed selection. The browser or the OS\n * took the gesture over, so this only lets go of the drag - it must not run\n * the pointer-up path, which advances hours to minutes, fires `onSelect`,\n * and under `autoSubmit` closes the picker on a time the user never chose.\n */\n _handleDocumentClickCancel = (e: PointerEvent) => {\n if (e.pointerId !== this._dragPointerId) return;\n this._dragPointerId = null;\n this.moved = false;\n this._drag.abort();\n };\n\n /**\n * Read `minTime` and `maxTime` as seconds of the day. Without a seconds\n * field the picker writes whole minutes, so the bounds round inward to a\n * whole minute: `maxTime` takes in every second of its minute, and the\n * hidden seconds never clamp.\n */\n private _readLimits() {\n const { minTime, maxTime, showSeconds, fromNow } = this.options;\n const read = (time: string | null, fallback: number) => (time ? daySeconds(readTime(time, fromNow)) : fallback);\n let [min, max] = [read(minTime, 0), read(maxTime, DAY_END)];\n if (!showSeconds) [min, max] = [Math.ceil(min / 60) * 60, Math.floor(max / 60) * 60 + 59];\n if (min > max) return console.warn('Timepicker ignored minTime and maxTime: minTime is after maxTime.', this.el);\n this._limits = [min, max];\n }\n\n _insertHTMLIntoDOM() {\n const template = document.createElement('template');\n template.innerHTML = Timepicker._template.trim();\n\n this.containerEl = <HTMLElement>template.content.firstChild;\n this.containerEl.id = 'container-' + this.id;\n\n // Append popover to input by default\n const optEl = this.options.container;\n const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);\n\n if (this.options.container && !!containerEl) {\n containerEl.append(this.containerEl);\n } else {\n this.el.parentElement.appendChild(this.containerEl);\n }\n }\n\n _setupVariables() {\n this.currentView = 'hours';\n // `navigator.webkitVibrate` never shipped in any browser - the probe it\n // came from was folklore. A plain feature check is the whole of it.\n this.canVibrate = typeof navigator.vibrate === 'function';\n this._canvas = this.containerEl.querySelector('.timepicker-canvas');\n this.plate = this.containerEl.querySelector('.timepicker-plate');\n this.digitalClock = this.containerEl.querySelector('.timepicker-display-column');\n this.hoursView = this.containerEl.querySelector('.timepicker-hours');\n this.minutesView = this.containerEl.querySelector('.timepicker-minutes');\n this.inputHours = this.containerEl.querySelector('.timepicker-input-hours');\n this.inputMinutes = this.containerEl.querySelector('.timepicker-input-minutes');\n this.inputSeconds = this.containerEl.querySelector('.timepicker-input-seconds');\n if (!this.options.showSeconds) this._removeSecondsField();\n // The fields are spin buttons: the arrows step them, and the hour and\n // minute fields move the hand.\n for (const unit of this._units()) {\n const [min, max] = this._bounds(unit);\n const attributes = { role: 'spinbutton', 'aria-valuemin': min, 'aria-valuemax': max, 'aria-label': this.options.i18n[unit] };\n Object.entries(attributes).forEach(([name, value]) => this._input(unit).setAttribute(name, String(value)));\n }\n this.spanAmPm = this.containerEl.querySelector('.timepicker-span-am-pm');\n this.footer = this.containerEl.querySelector('.timepicker-footer');\n this.amOrPm = 'PM';\n }\n\n private _removeSecondsField() {\n this.containerEl.querySelectorAll('.timepicker-seconds-divider, .timepicker-input-seconds-wrapper').forEach((el) => el.remove());\n this.inputSeconds = null;\n }\n\n private _input(unit: Unit): HTMLInputElement | null {\n return { hours: this.inputHours, minutes: this.inputMinutes, seconds: this.inputSeconds }[unit];\n }\n\n /** The units that have a field. */\n private _units(): Unit[] {\n return UNITS.filter((unit) => this._input(unit));\n }\n\n /** Which unit's field `target` is, if any. */\n private _unitOf(target: EventTarget): Unit | undefined {\n return this._units().find((unit) => this._input(unit) === target);\n }\n\n _pickerSetup() {\n pickerFooter(this.footer, this.options, 'timepicker-clear', this.clear, this.confirm, this.cancel);\n\n this._updateTimeFromInput();\n\n // With a docked display the container is `visibility: hidden` until\n // show(), so the dial can wait for the first interaction. Without one it\n // is on screen from the moment it is inserted and has to be ready now.\n if (!this.options.displayPlugin) this.showView('hours');\n }\n\n /**\n * Build the dial, once. Cheap to call repeatedly - every entry point that\n * touches the clock calls it first, so the picker cannot be interacted with\n * before it exists.\n */\n private _ensureClockBuilt() {\n if (this._clockBuilt) return;\n this._clockBuilt = true;\n this._clockSetup();\n // Applies the AM/PM state _updateTimeFromInput worked out before the\n // buttons existed.\n this._updateAmPmView();\n this._updateRanges();\n }\n\n _clockSetup() {\n if (this.options.twelveHour) {\n // AM Button\n this._amBtn = document.createElement('button');\n this._amBtn.type = 'button';\n this._amBtn.classList.add('am-btn');\n this._amBtn.innerText = 'AM';\n this._amBtn.addEventListener('click', this._handleAmPmClick);\n this.spanAmPm.appendChild(this._amBtn);\n // PM Button\n this._pmBtn = document.createElement('button');\n this._pmBtn.type = 'button';\n this._pmBtn.classList.add('pm-btn');\n this._pmBtn.innerText = 'PM';\n this._pmBtn.addEventListener('click', this._handleAmPmClick);\n this.spanAmPm.appendChild(this._pmBtn);\n }\n this._buildHoursView();\n this._buildMinutesView();\n this._buildSVGClock();\n }\n\n _buildSVGClock() {\n // Draw clock hands and others\n const dialRadius = this.options.dialRadius;\n const tickRadius = this.options.tickRadius;\n const diameter = dialRadius * 2;\n // The ticks, hand and pointer math all centre on dialRadius, so the\n // painted face has to be the same size or the hand sits off centre.\n this.plate.style.width = this.plate.style.height = diameter + 'px';\n const svg = svgNode('svg', { class: 'timepicker-svg', width: String(diameter), height: String(diameter) });\n const g = svgNode('g', { transform: `translate(${dialRadius},${dialRadius})` });\n const bearing = svgNode('circle', { class: 'timepicker-canvas-bearing', cx: '0', cy: '0', r: '4' });\n const hand = svgNode('line', { x1: '0', y1: '0' });\n const bg = svgNode('circle', { class: 'timepicker-canvas-bg', r: String(tickRadius) });\n g.appendChild(hand);\n g.appendChild(bg);\n g.appendChild(bearing);\n svg.appendChild(g);\n this._canvas.appendChild(svg);\n this.hand = hand;\n this.bg = bg;\n this.g = g;\n }\n\n _buildHoursView() {\n // Hours view\n if (this.options.twelveHour) {\n for (let i = 1; i < 13; i += 1) {\n const radian = (i / 6) * Math.PI;\n const radius = this.options.outerRadius;\n this._buildHoursTick(i, radian, radius);\n }\n } else {\n for (let i = 0; i < 24; i += 1) {\n const radian = (i / 6) * Math.PI;\n const inner = i > 0 && i < 13;\n const radius = inner ? this.options.innerRadius : this.options.outerRadius;\n this._buildHoursTick(i, radian, radius);\n }\n }\n }\n\n _buildHoursTick(i: number, radian: number, radius: number) {\n this._placeTick(this.hoursView, radian, radius, i === 0 ? '00' : i.toString());\n }\n\n _buildMinutesView() {\n for (let i = 0; i < 60; i += 5) {\n const radian = (i / 30) * Math.PI;\n this._placeTick(this.minutesView, radian, this.options.outerRadius, pad2(i));\n }\n }\n\n private _placeTick(view: HTMLElement, radian: number, radius: number, text: string) {\n const tick = document.createElement('div');\n tick.classList.add('timepicker-tick');\n tick.style.left =\n this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px';\n tick.style.top =\n this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px';\n tick.textContent = text;\n view.appendChild(tick);\n }\n\n _handleAmPmClick = (e: MouseEvent) => {\n this._handleAmPmInteraction(<HTMLElement>e.target);\n };\n\n _handleAmPmInteraction = (e: HTMLElement) => {\n this.amOrPm = e.classList.contains('am-btn') ? 'AM' : 'PM';\n this._updateAmPmView();\n this._afterChange();\n this.resetClock(null);\n }\n\n _updateAmPmView() {\n // _updateTimeFromInput settles amOrPm before the dial is built; the\n // buttons pick the state up in _ensureClockBuilt.\n if (!this._amBtn || !this._pmBtn) return;\n this._amBtn.setAttribute('aria-pressed', String(this.amOrPm === 'AM'));\n this._pmBtn.setAttribute('aria-pressed', String(this.amOrPm === 'PM'));\n this._amBtn.classList.toggle('outlined', this.amOrPm !== 'AM');\n this._pmBtn.classList.toggle('outlined', this.amOrPm !== 'PM');\n if (this.options.twelveHour) {\n if (this.amOrPm === 'PM') {\n this._amBtn.classList.remove('filled');\n this._pmBtn.classList.add('filled');\n } else if (this.amOrPm === 'AM') {\n this._amBtn.classList.add('filled');\n this._pmBtn.classList.remove('filled');\n }\n }\n }\n\n _updateTimeFromInput() {\n this._cancelClockReset();\n const [hours, minutes, seconds] = readTime(`${this.el.value || this.options.defaultTime || ''}`, this.options.fromNow);\n [this.minutes, this.seconds] = [minutes, seconds];\n this._setHours24(hours);\n this._clamp();\n this._writeFields();\n this._updateAmPmView();\n this._updateRanges();\n }\n\n /** Show the time in every field but `except`, which the person is typing in. */\n private _writeFields(except?: HTMLInputElement) {\n this._units().forEach((unit) => {\n if (this._input(unit) !== except) this._input(unit).value = pad2(this[unit]);\n });\n }\n\n /** After a change to the time: keep it in range and update what depends on it. */\n private _afterChange(except?: HTMLInputElement) {\n if (this._clamp()) this._writeFields(except);\n this._updateRanges();\n }\n\n /**\n * Give each field the allowed range of values, and disable a period with\n * no allowed time.\n */\n private _updateRanges() {\n for (const unit of this._units()) {\n const [min, max] = this._range(unit);\n this._input(unit).setAttribute('aria-valuemin', String(min));\n this._input(unit).setAttribute('aria-valuemax', String(max));\n }\n const [first, last] = this._dayRange('hours');\n if (this._amBtn) [this._amBtn.disabled, this._pmBtn.disabled] = [first > 11, last < 12];\n this._disableTicks(this.hoursView, 'hours');\n this._disableTicks(this.minutesView, 'minutes');\n }\n\n /** Mark the ticks of a dial view that are outside the range. */\n private _disableTicks(view: HTMLElement, unit: Unit) {\n view.querySelectorAll('.timepicker-tick').forEach((tick) => {\n tick.classList.toggle('is-disabled', !this._allows(unit, Number(tick.textContent)));\n });\n }\n\n /** The hour on the 24-hour clock, setting AM or PM on a 12-hour one. */\n private _setHours24(hour: number) {\n if (!this.options.twelveHour) return void (this.hours = hour);\n this.amOrPm = hour >= 12 ? 'PM' : 'AM';\n this.hours = hour % 12 || 12;\n this._updateAmPmView();\n }\n\n /** The time as seconds of the day. */\n private _time() {\n return daySeconds([this._dayValue('hours', this.hours), this.minutes, this.seconds]);\n }\n\n /** Move the time to the nearest allowed time, and say whether it moved. */\n private _clamp() {\n const time = this._time();\n const clamped = Math.min(Math.max(time, this._limits[0]), this._limits[1]);\n if (clamped === time) return false;\n this._setHours24(Math.floor(clamped / 3600));\n [this.minutes, this.seconds] = [Math.floor(clamped / 60) % 60, clamped % 60];\n return true;\n }\n\n /**\n * Show hours or minutes view on timepicker.\n * @param view The name of the view you want to switch to, 'hours' or 'minutes'.\n * @param delay\n */\n showView = (view: Views, delay: number = null) => {\n this._ensureClockBuilt();\n const isHours = view === 'hours',\n nextView = isHours ? this.hoursView : this.minutesView,\n hideView = isHours ? this.minutesView : this.hoursView;\n this.currentView = view;\n\n // Transition view\n hideView.classList.add('timepicker-dial-out');\n\n nextView.style.visibility = 'visible';\n nextView.classList.remove('timepicker-dial-out');\n\n // Reset clock hand\n this.resetClock(delay);\n // After transitions ended\n clearTimeout(this.toggleViewTimer);\n this.toggleViewTimer = setTimeout(() => {\n hideView.style.visibility = 'hidden';\n }, this.options.duration);\n };\n\n private _cancelClockReset() {\n clearTimeout(this._clockResetTimer);\n this._clockResetTimer = null;\n this._canvas?.classList.remove('timepicker-canvas-out');\n }\n\n resetClock(delay) {\n this._cancelClockReset();\n const view = this.currentView,\n value = this[view],\n isHours = view === 'hours',\n unit = Math.PI / (isHours ? 6 : 30),\n radian = value * unit,\n radius =\n isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius,\n x = Math.sin(radian) * radius,\n y = -Math.cos(radian) * radius;\n\n if (delay) {\n this._canvas?.classList.add('timepicker-canvas-out');\n this._clockResetTimer = setTimeout(() => {\n this.setHand(x, y);\n }, delay);\n } else {\n this.setHand(x, y);\n }\n }\n\n /**\n * Enter in the hour or minute field commits the typed time. The dial ticks\n * are pointer targets only, and under `autoSubmit` there is no Ok button,\n * so without this a keyboard user could type a time but never set it.\n * Cancelling also keeps Enter from submitting a surrounding form. The\n * listener's column holds only the fields; AM/PM is a separate column.\n */\n _handleDigitalKeydown = Utils.ignoringComposition((event: KeyboardEvent) => {\n if (event.key in STEPS) return this._step(event);\n if (event.key !== 'Enter') return;\n event.preventDefault();\n // Normalize first, as leaving the field would: an emptied field takes its\n // default, and the committed time has to be the one the fields then show.\n this._formatFields();\n if (this.options.autoSubmit) this.done();\n else this.confirm();\n });\n\n /** The lowest and highest value a field can show. */\n private _bounds(unit: Unit): [number, number] {\n if (unit !== 'hours') return [0, 59];\n return this.options.twelveHour ? [1, 12] : [0, 23];\n }\n\n /** The lowest and highest allowed value of a field, given the others. */\n private _range(unit: Unit): [number, number] {\n const [min, max] = this._bounds(unit);\n const allowed = Array.from({ length: max - min + 1 }, (_, i) => min + i).filter((value) => this._allows(unit, value));\n return allowed.length ? [Math.min(...allowed), Math.max(...allowed)] : [min, max];\n }\n\n /**\n * The first and last allowed value of a field, given the fields before it,\n * with hours on the 24-hour clock. An hour is allowed when any second of\n * it is, and so is a minute.\n */\n private _dayRange(unit: Unit): number[] {\n const [size, count] = SPANS[unit];\n const start = this._time() - (this._time() % (size * count));\n return this._limits.map((limit) => Math.min(Math.max(Math.floor((limit - start) / size), 0), count - 1));\n }\n\n /** A field's value with hours on the 24-hour clock. */\n private _dayValue(unit: Unit, value: number) {\n return unit === 'hours' && this.options.twelveHour ? dayHour(value, this.amOrPm === 'PM') : value;\n }\n\n /** Whether a field can take `value` within the range. */\n private _allows(unit: Unit, value: number) {\n const [first, last] = this._dayRange(unit);\n const day = this._dayValue(unit, value);\n return Math.min(Math.max(day, first), last) === day;\n }\n\n /** The whole number typed in a field, or NaN when the field can't take it. */\n private _fieldValue(unit: Unit, text: string) {\n const value = Number(text.trim() || NaN);\n return this._takes(unit, value) ? value : NaN;\n }\n\n /** Whether a field can show `value` and the range allows it. */\n private _takes(unit: Unit, value: number) {\n const [min, max] = this._bounds(unit);\n return Number.isInteger(value) && Math.min(Math.max(value, min), max) === value && this._allows(unit, value);\n }\n\n /** Point the hand at an hour or minute. Seconds have no dial view. */\n private _moveHand(unit: Unit, value: number) {\n if (unit === 'seconds') return;\n this._cancelClockReset();\n this.drawClockFromTimeInput(value, unit === 'hours');\n }\n\n /**\n * Up and Down step a field by one, Page Up and Page Down by five, round\n * the dial: past 59 minutes comes 00. The hand follows hours and minutes.\n * Hours step round the day, so in 12-hour time passing 12 switches AM and\n * PM. Minutes and seconds wrap without carrying. With `minTime` or\n * `maxTime`, a field that is not wholly allowed stops at its last allowed\n * value instead of wrapping.\n */\n private _step(event: KeyboardEvent) {\n const input = event.target as HTMLInputElement;\n const unit = this._unitOf(input);\n if (!unit) return;\n event.preventDefault();\n const value = this._stepValue(unit, STEPS[event.key]);\n if (unit === 'hours') this._setHours24(value);\n else this[unit] = value;\n this._afterChange();\n input.value = pad2(this[unit]);\n this._moveHand(unit, this[unit]);\n }\n\n /** A field's value `step` on, with hours on the 24-hour clock. */\n private _stepValue(unit: Unit, step: number) {\n const [first, last] = this._dayRange(unit);\n const count = SPANS[unit][1];\n const next = this._dayValue(unit, this[unit]) + step;\n return first === 0 && last === count - 1 ? (next + count) % count : Math.min(Math.max(next, first), last);\n }\n\n _inputFromTextField = (event: Event) => {\n const input = event.target as HTMLInputElement;\n const unit = this._unitOf(input);\n if (!unit) return;\n // Any edit to an hour or minute cancels an older delayed hand move.\n if (unit !== 'seconds') this._cancelClockReset();\n const value = this._fieldValue(unit, input.value);\n if (Number.isNaN(value)) return;\n this[unit] = value;\n this._afterChange(input);\n this._moveHand(unit, value);\n };\n\n drawClockFromTimeInput(value, isHours) {\n const unit = Math.PI / (isHours ? 6 : 30);\n const radian = value * unit;\n let radius;\n if (this.options.twelveHour) {\n radius = this.options.outerRadius;\n } else {\n radius =\n isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius;\n }\n this.setClockAttributes(radian, radius);\n }\n\n setHand(x, y, roundBy5: boolean = false) {\n this._cancelClockReset();\n const isHours = this.currentView === 'hours',\n unit = Math.PI / (isHours || roundBy5 ? 6 : 30),\n z = Math.sqrt(x * x + y * y),\n inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2;\n const radius = inner && !this.options.twelveHour ? this.options.innerRadius : this.options.outerRadius;\n let radian = Math.atan2(x, -y);\n\n // Radian should in range [0, 2PI]\n if (radian < 0) {\n radian = Math.PI * 2 + radian;\n }\n\n // Get the round value\n const position = Math.round(radian / unit);\n\n // Get the round radian\n radian = position * unit;\n\n const value = isHours ? this._hourAt(position, inner) : ((roundBy5 ? position * 5 : position) % 60);\n // The hand stays on the last allowed value.\n this._handRefused = !this._allows(this.currentView, value);\n if (this._handRefused) return;\n\n // Once hours or minutes changed, vibrate the device. The timer keeps it\n // from vibrating too frequently.\n if (this[this.currentView] !== value && this.canVibrate && this.options.vibrate && !this.vibrateTimer) {\n navigator.vibrate(10);\n this.vibrateTimer = setTimeout(() => {\n this.vibrateTimer = null;\n }, 100);\n }\n\n this[this.currentView] = value;\n (isHours ? this.inputHours : this.inputMinutes).value = pad2(value);\n\n // Set clock hand and others' position\n this.setClockAttributes(radian, radius);\n this._afterChange();\n }\n\n /** The hour at a dial position, 0 to 12 from the top. */\n private _hourAt(position: number, inner: boolean) {\n return this.options.twelveHour ? position % 12 || 12 : ringHour(position, inner);\n }\n\n setClockAttributes(radian: number, radius: number) {\n // Nothing to point at until the SVG exists.\n if (!this.hand || !this.bg) return;\n const cx1 = Math.sin(radian) * (radius - this.options.tickRadius),\n cy1 = -Math.cos(radian) * (radius - this.options.tickRadius),\n cx2 = Math.sin(radian) * radius,\n cy2 = -Math.cos(radian) * radius;\n this.hand.setAttribute('x2', cx1.toString());\n this.hand.setAttribute('y2', cy1.toString());\n this.bg.setAttribute('cx', cx2.toString());\n this.bg.setAttribute('cy', cy2.toString());\n }\n\n formatHours() {\n if (this.inputHours.value == '') this.setHoursDefault();\n this.inputHours.value = pad2(this.hours);\n }\n\n formatMinutes() {\n if (this.inputMinutes.value == '') this.minutes = new Date().getMinutes();\n this.inputMinutes.value = pad2(this.minutes);\n }\n\n formatSeconds() {\n if (this.inputSeconds.value == '') this.seconds = new Date().getSeconds();\n this.inputSeconds.value = pad2(this.seconds);\n }\n\n /** Normalize every field, as leaving it would. */\n private _formatFields() {\n this.formatHours();\n this.formatMinutes();\n if (this.inputSeconds) this.formatSeconds();\n }\n\n setHoursDefault() {\n this.hours = new Date().getHours();\n if (this.options.twelveHour) this.hours = this.hours % 12 || 12;\n this.inputHours.value = this.hours.toString();\n }\n\n done = (clearValue = null) => {\n // Set input value\n const last = this.el.value;\n let value = clearValue ? '' : this._clockTime(this.hours);\n this.time = value;\n if (!clearValue) value = this._inputValue(value);\n this.el.value = value;\n // Trigger change event\n if (value !== last) {\n this.el.dispatchEvent(\n new Event('change', { bubbles: true, cancelable: true, composed: true })\n );\n }\n };\n\n /** `HH:MM` for the given hour, or `HH:MM:SS` with a seconds field. */\n private _clockTime(hours: number) {\n const parts = this.inputSeconds ? [hours, this.minutes, this.seconds] : [hours, this.minutes];\n return parts.map(pad2).join(':');\n }\n\n // A time input accepts only 24-hour HH:mm or HH:mm:ss and empties itself\n // on anything else, so it never gets the AM/PM a text input shows.\n private _inputValue(time: string) {\n if (this.el.type === 'time') return this._clockTime(this._dayValue('hours', this.hours));\n return this.options.twelveHour ? `${time} ${this.amOrPm}` : time;\n }\n\n confirm = () => {\n this.done();\n hideModal(this.displayPlugin);\n this._notify('confirm', this.options.onDone, { args: [] });\n }\n\n cancel = () => {\n // Cancel keeps the previously submitted value in the input.\n hideModal(this.displayPlugin);\n this._notify('cancel', this.options.onCancel, { args: [] });\n }\n\n clear = () => {\n this.done(true);\n };\n\n static {\n Timepicker._template = `<div class=\"timepicker-container\">\n <div class=\"timepicker-digital-display\">\n <div class=\"timepicker-text-container\">\n <div class=\"timepicker-display-column timepicker-display-digital-clock\">\n <div class=\"timepicker-input-hours-wrapper\">\n <input type=\"text\" maxlength=\"2\" class=\"timepicker-input-hours\" />\n </div>\n <div class=\"timepicker-input-divider-wrapper\">\n <span class=\"timepicker-input-divider\">:</span>\n </div>\n <div class=\"timepicker-input-minutes-wrapper\">\n <input type=\"text\" maxlength=\"2\" class=\"timepicker-input-minutes\" />\n </div>\n <div class=\"timepicker-input-divider-wrapper timepicker-seconds-divider\">\n <span class=\"timepicker-input-divider\">:</span>\n </div>\n <div class=\"timepicker-input-seconds-wrapper\">\n <input type=\"text\" maxlength=\"2\" class=\"timepicker-input-seconds\" />\n </div>\n </div>\n <div class=\"timepicker-display-column timepicker-display-am-pm\">\n <div class=\"timepicker-span-am-pm\"></div>\n </div>\n </div>\n </div>\n <div class=\"timepicker-analog-display\">\n <div class=\"timepicker-plate\">\n <div class=\"timepicker-canvas\"></div>\n <div class=\"timepicker-dial timepicker-hours\"></div>\n <div class=\"timepicker-dial timepicker-minutes timepicker-dial-out\"></div>\n </div>\n <div class=\"timepicker-footer\"></div>\n </div>\n </div>`;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/snackbar.ts"],
4
- "sourcesContent": ["import { BaseOptions } from '../core/component';\nimport { Utils, controllerFor, restoreAttribute } from '../core/utils';\n\nexport interface SnackbarOptions extends BaseOptions {\n /**\n * The content of the Snackbar.\n * @default \"\"\n */\n text: string;\n /**\n * Optional action label. Rendered as a trailing text button.\n * @default \"\"\n */\n action: string;\n /**\n * Called when the action button is pressed. The snackbar still dismisses.\n * @default null\n */\n onAction: () => void;\n /**\n * Show a trailing close icon button.\n * Defaults to true when action is set, otherwise false.\n */\n dismissible: boolean;\n /**\n * Element id of a `<template>` (or another element) used as the snackbar body.\n * @default \"\"\n */\n snackbarId?: string;\n /**\n * Length in ms the Snackbar stays before dismissal.\n * `Infinity` keeps it on screen until the user acts.\n * When `action` is set and this is omitted, the default is Infinity.\n * @default 4000\n */\n displayLength: number;\n /**\n * Transition in duration in milliseconds.\n * @default 300\n */\n inDuration: number;\n /**\n * Transition out duration in milliseconds.\n * @default 375\n */\n outDuration: number;\n /**\n * Classes to be added to the snackbar element.\n * @default \"\"\n */\n classes: string;\n /**\n * Callback function called when the snackbar is dismissed.\n * @default null\n */\n completeCallback: () => void;\n /**\n * The percentage of the snackbar's width it takes for a drag\n * to dismiss a Snackbar.\n * @default 0.8\n */\n activationPercent: number;\n /**\n * Any element in the tree the snackbar should render into. A Snackbar has no\n * originating element to infer this from, so pass one when the page lives in\n * a shadow root \u2014 the container is appended to that root instead of to\n * `document.body`, where a root-scoped stylesheet could not reach it.\n * @default null\n */\n root: HTMLElement;\n /**\n * Show at once, dismissing the snackbar on screen without its exit\n * animation, instead of waiting in the queue behind it.\n * @default false\n */\n replace: boolean;\n}\n\nconst _defaults: SnackbarOptions = {\n text: '',\n action: '',\n onAction: null,\n dismissible: false,\n displayLength: 4000,\n inDuration: 300,\n outDuration: 375,\n classes: '',\n completeCallback: null,\n activationPercent: 0.8,\n root: null,\n replace: false\n};\n\nexport class Snackbar {\n /** The snackbar element. */\n el: HTMLElement;\n /**\n * The remaining amount of time in ms that the snackbar\n * will stay before dismissal.\n */\n timeRemaining: number;\n /**\n * Describes the current pan state of the Snackbar.\n */\n panning: boolean;\n options: SnackbarOptions;\n message: string;\n counterTimeout: ReturnType<typeof setTimeout>;\n /** Wall-clock time the snackbar is due to dismiss, for pause/resume. */\n private _deadline: number;\n wasSwiped: boolean;\n startingXPos: number;\n xPos: number;\n time: number;\n deltaX: number;\n velocityX: number;\n /** Swipe distance that dismisses, measured once when the drag starts. */\n private _activationDistance: number;\n private _dismissed = false;\n private _returnFocus: HTMLElement | null = null;\n /** The document body or shadow root the snackbar renders into. */\n private _portal: HTMLElement | ShadowRoot;\n private _events: AbortController;\n private _restoreElement: (() => void) | null = null;\n private _transitionTimer: ReturnType<typeof setTimeout>;\n private _dismissTimer: ReturnType<typeof setTimeout>;\n private _focusTimer: ReturnType<typeof setTimeout>;\n\n /** The snackbar on screen, kept until its exit animation finishes. */\n static _snackbars: Snackbar[];\n /** Snackbars waiting for the one on screen to leave, oldest first. */\n static _queue: Snackbar[];\n /** Set while a replacement clears the screen; the queue waits for it. */\n private static _replacing = false;\n static _container: HTMLElement;\n static _draggedSnackbar: Snackbar;\n /** Which pointer owns the drag in flight; a second finger is ignored. */\n static _dragPointerId: number | null = null;\n\n /**\n * Whether a bar gets its close button when the page does not say. One with\n * an action waits for it, and one that never times out waits for the\n * reader; either way, swiping must not be the only way to send it off.\n */\n private static _needsClose(options: SnackbarOptions): boolean {\n return !!options.action || options.displayLength === Infinity;\n }\n\n constructor(options: Partial<SnackbarOptions> = {}) {\n this.options = {\n ...Snackbar.defaults,\n ...options\n };\n if (options.displayLength === undefined && this.options.action) {\n this.options.displayLength = Infinity;\n }\n if (options.dismissible === undefined) this.options.dismissible = Snackbar._needsClose(this.options);\n this.message = this.options.text;\n this.panning = false;\n this.timeRemaining = this.options.displayLength;\n // Worked out now: `root` may be inside the snackbar this one replaces,\n // and gone by the time it shows.\n this._portal = Utils.portalRoot(this.options.root ?? document.body);\n // First, so an authored body a re-render orphaned is back in its place.\n Snackbar._dropDetached();\n // An authored body is taken when the snackbar shows: one waiting in the\n // queue must not claim the element the snackbar on screen is using.\n if (this.options.snackbarId) this._requireBody();\n else this._build();\n // One snackbar at a time, as Material asks. Everything goes through the\n // queue, so arrivals show in order; a replacement goes to its front once\n // the screen is cleared.\n if (this.options.replace) Snackbar._replaceShown(this);\n else Snackbar._queue.push(this);\n Snackbar._advance();\n }\n\n /**\n * Lets go of snackbars a re-render took out of the page. A persistent one\n * would otherwise hold the queue for good.\n */\n private static _dropDetached() {\n for (const snackbar of Snackbar._snackbars.filter((shown) => !shown.el.isConnected)) {\n snackbar._dismissed = true;\n snackbar._remove(false);\n }\n }\n\n /** Throws now, rather than when the snackbar shows, if `snackbarId` names nothing. */\n private _requireBody() {\n if (!this._hasBody()) throw new Error('Snackbar body not found');\n }\n\n /** Whether the body a snackbar shows is still there: its own, or `snackbarId`'s. */\n private _hasBody(): boolean {\n return !this.options.snackbarId || !!Utils.getElementById(this._portal, this.options.snackbarId);\n }\n\n private _build() {\n this.el = this._createSnackbar();\n this.el['Expressive_Snackbar'] = this;\n }\n\n /**\n * Takes the snackbar on screen down at once, without starting the queue.\n * Restoring focus can open another, which goes too.\n */\n private static _replaceShown(replacement: Snackbar) {\n // A snackbar opened by the focus restore below must not start the queue,\n // or the next waiting one would show only to be cut short here.\n Snackbar._replacing = true;\n try {\n while (Snackbar._snackbars.length) {\n for (const snackbar of Snackbar._snackbars.splice(0)) {\n snackbar._dismissed = true;\n snackbar._restoreFocus(true);\n }\n }\n } finally {\n Snackbar._replacing = false;\n }\n Snackbar._queue.unshift(replacement);\n }\n\n /** Puts the snackbar on screen and starts its countdown. */\n private _show() {\n if (!this.el) this._build();\n this._returnFocus = Snackbar._focused();\n Snackbar._containerIn(this._portal).appendChild(this.el);\n Snackbar._snackbars.push(this);\n this._animateIn();\n this._setTimer();\n Utils.emit(this.el, 'open');\n }\n\n /** The focused element, looking inside open shadow roots. */\n private static _focused(): HTMLElement | null {\n let focused = document.activeElement;\n while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;\n return focused instanceof HTMLElement ? focused : null;\n }\n\n /**\n * One container serves every snackbar, and only one snackbar shows at a\n * time \u2014 so it is moved rather than duplicated when the root changes.\n */\n private static _containerIn(root: HTMLElement | ShadowRoot): HTMLElement {\n const container = Snackbar._container;\n if (container?.isConnected && container.parentNode === root) return container;\n Snackbar._removeContainer();\n Snackbar._createContainer(root);\n return Snackbar._container;\n }\n\n static get defaults(): SnackbarOptions {\n return _defaults;\n }\n\n static getInstance(el: HTMLElement): Snackbar {\n return el['Expressive_Snackbar'];\n }\n\n static _createContainer(root: HTMLElement | ShadowRoot = document.body) {\n const container = document.createElement('div');\n container.setAttribute('id', 'snackbar-container');\n // One listener per stage. These used to be a touch trio on the container\n // plus a mouse trio split across the container and the document, with a\n // helper picking `targetTouches[0].clientX` or `clientX` apart afterwards.\n // Move and up stay on the document so a drag that leaves the container\n // still completes.\n container.addEventListener('pointerdown', Snackbar._onDragStart);\n document.addEventListener('pointermove', Snackbar._onDragMove);\n document.addEventListener('pointerup', Snackbar._onDragEnd);\n document.addEventListener('pointercancel', Snackbar._onDragCancel);\n root.appendChild(container);\n Snackbar._container = container;\n }\n\n static _removeContainer() {\n document.removeEventListener('pointermove', Snackbar._onDragMove);\n document.removeEventListener('pointerup', Snackbar._onDragEnd);\n document.removeEventListener('pointercancel', Snackbar._onDragCancel);\n Snackbar._container?.remove();\n Snackbar._container = null;\n }\n\n static _onDragStart(e: PointerEvent) {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n const target = e.target as HTMLElement | null;\n // Don't start a swipe from the action or close \u2014 those are buttons.\n if (target && !target.closest('button, a') && target.closest('.snackbar')) {\n const snackbarElem = target.closest('.snackbar') as HTMLElement;\n const snackbar: Snackbar = snackbarElem['Expressive_Snackbar'];\n if (!snackbar) return;\n snackbar.panning = true;\n snackbar._pauseTimer();\n Snackbar._draggedSnackbar = snackbar;\n snackbar.el.classList.add('panning');\n snackbar.el.style.transition = '';\n Snackbar._dragPointerId = e.pointerId;\n snackbar.startingXPos = e.clientX;\n snackbar.velocityX = 0;\n snackbar.time = Date.now();\n snackbar.xPos = e.clientX;\n // A translateX does not change the width, so one read covers the drag.\n snackbar._activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;\n }\n }\n\n static _onDragMove(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n if (!!Snackbar._draggedSnackbar) {\n e.preventDefault();\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);\n snackbar.xPos = e.clientX;\n // Two moves in the same millisecond would divide by zero, and an\n // infinite velocity dismisses on release.\n snackbar.velocityX = snackbar.deltaX / Math.max(1, Date.now() - snackbar.time);\n snackbar.time = Date.now();\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar._activationDistance;\n snackbar.el.style.transform = `translateX(${totalDeltaX}px)`;\n snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();\n }\n }\n\n static _onDragEnd(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n if (!!Snackbar._draggedSnackbar) {\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar._activationDistance;\n const velocity = Date.now() - snackbar.time < 100 ? snackbar.velocityX : 0;\n const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || velocity > 1;\n\n // Remove snackbar\n if (shouldBeDismissed) {\n snackbar.wasSwiped = true;\n snackbar.dismiss();\n // Animate snackbar back to original position\n } else {\n snackbar._snapBack();\n }\n Snackbar._draggedSnackbar = null;\n }\n }\n\n /**\n * A cancelled pointer is not a short swipe. Snap back and resume the timer\n * without consulting the distance travelled - the browser took the gesture\n * over, so the movement so far says nothing about what the user wanted.\n */\n static _onDragCancel(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n const snackbar = Snackbar._draggedSnackbar;\n if (!snackbar) return;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n snackbar._snapBack();\n Snackbar._draggedSnackbar = null;\n }\n\n private _snapBack() {\n this.el.style.transition = 'transform .2s, opacity .2s';\n this.el.style.transform = '';\n this.el.style.opacity = '';\n this._resumeTimer();\n }\n\n /**\n * dismiss all snackbars.\n */\n static dismissAll() {\n // The queue first, so the one on screen does not hand over to it. Copy\n // first: dismiss() splices the lists it is iterating.\n for (const snackbar of [...Snackbar._queue, ...Snackbar._snackbars]) {\n snackbar.dismiss();\n }\n }\n\n /**\n * Whether dismiss() is done already: the snackbar was dismissed before, or\n * never showed and is dropped from the queue. A dropped one reports through\n * completeCallback but fires no events, never having been in the page.\n */\n private _leaveQueue(): boolean {\n if (this._dismissed) return true;\n const index = Snackbar._queue.indexOf(this);\n if (index < 0) return false;\n Snackbar._queue.splice(index, 1);\n this._drop();\n return true;\n }\n\n private _drop() {\n this._dismissed = true;\n // An authored body was never taken, so there is nothing to give back.\n if (this.el) this._remove(false);\n this.options.completeCallback?.();\n }\n\n _createSnackbar() {\n let snackbar: HTMLElement = this.options.snackbarId\n ? Utils.getElementById(this._portal, this.options.snackbarId)\n : document.createElement('div');\n if (snackbar instanceof HTMLTemplateElement) {\n const node = snackbar.content.cloneNode(true);\n snackbar = (node as HTMLElement).firstElementChild as HTMLElement;\n } else if (snackbar && this.options.snackbarId) {\n const placeholder = document.createComment('');\n snackbar.before(placeholder);\n const children = [...snackbar.childNodes];\n const attributes = ['class', 'style', 'role', 'aria-live', 'aria-atomic', 'inert']\n .map(name => [name, snackbar.getAttribute(name)]);\n this._restoreElement = () => {\n snackbar.replaceChildren(...children);\n for (const [name, value] of attributes) restoreAttribute(snackbar, name, value);\n placeholder.replaceWith(snackbar);\n };\n }\n if (!snackbar) throw new Error('Snackbar body not found');\n this._events = controllerFor(snackbar);\n const listenerOptions = { signal: this._events.signal };\n snackbar.classList.add('snackbar');\n snackbar.setAttribute('role', 'status');\n snackbar.setAttribute('aria-live', 'polite');\n snackbar.setAttribute('aria-atomic', 'true');\n snackbar.inert = false;\n snackbar.addEventListener('focusin', (e) => {\n if (e.relatedTarget instanceof HTMLElement && !snackbar.contains(e.relatedTarget)) {\n this._returnFocus = e.relatedTarget;\n }\n this._pauseTimer();\n }, listenerOptions);\n snackbar.addEventListener('keydown', (e) => {\n if (e.key !== 'Escape' || e.defaultPrevented || this._dismissed) return;\n e.preventDefault();\n e.stopPropagation();\n this.dismiss();\n }, listenerOptions);\n snackbar.addEventListener('focusout', () => {\n clearTimeout(this._focusTimer);\n this._focusTimer = setTimeout(() => this._resumeTimer(), 0);\n }, listenerOptions);\n snackbar.addEventListener('pointerenter', () => this._pauseTimer(), listenerOptions);\n snackbar.addEventListener('pointerleave', () => this._resumeTimer(), listenerOptions);\n // Add custom classes onto snackbar\n if (this.options.classes.length > 0) {\n snackbar.classList.add(...this.options.classes.split(' ').filter(Boolean));\n }\n if (this.message) {\n const text = document.createElement('p');\n text.textContent = this.message;\n snackbar.replaceChildren(text);\n }\n if (this.options.action) {\n const action = document.createElement('button');\n action.type = 'button';\n action.textContent = this.options.action;\n action.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this._dismissed) return;\n try {\n if (typeof this.options.onAction === 'function') this.options.onAction();\n Utils.emit(this.el, 'action');\n } finally {\n this.dismiss();\n }\n }, listenerOptions);\n snackbar.appendChild(action);\n }\n if (this.options.dismissible) {\n const close = document.createElement('button');\n close.type = 'button';\n close.className = 'circle';\n close.setAttribute('aria-label', 'Dismiss');\n const icon = document.createElement('span');\n icon.className = 'material-symbols';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = 'close';\n close.appendChild(icon);\n close.addEventListener('click', (e) => {\n e.stopPropagation();\n this.dismiss();\n }, listenerOptions);\n snackbar.appendChild(close);\n }\n return snackbar;\n }\n\n private _remove(advance = true) {\n if (this._events.signal.aborted) return;\n this._events.abort();\n clearTimeout(this.counterTimeout);\n clearTimeout(this._transitionTimer);\n clearTimeout(this._dismissTimer);\n clearTimeout(this._focusTimer);\n this.counterTimeout = null;\n if (Snackbar._draggedSnackbar === this) {\n Snackbar._draggedSnackbar = null;\n Snackbar._dragPointerId = null;\n }\n this.el['Expressive_Snackbar'] = undefined;\n if (this._restoreElement) this._restoreElement();\n else this.el.remove();\n const index = Snackbar._snackbars.indexOf(this);\n if (index >= 0) Snackbar._snackbars.splice(index, 1);\n if (advance) Snackbar._advance();\n }\n\n /** Shows the next queued snackbar once the screen is clear, or tidies up. */\n private static _advance() {\n while (!Snackbar._replacing && !Snackbar._snackbars.length) {\n const next = Snackbar._queue.shift();\n if (!next) return Snackbar._tidy();\n Snackbar._showOrDrop(next);\n }\n }\n\n /**\n * A queued snackbar completes without showing when the page it was for has\n * gone: its `root`, such as a removed shadow host, or its authored body.\n * Shown there, nothing could reach it to dismiss it, and the queue would stall.\n */\n private static _showOrDrop(next: Snackbar) {\n if (Snackbar._canShow(next)) next._show();\n else next._drop();\n }\n\n private static _canShow(next: Snackbar): boolean {\n if (!next._portal.isConnected) return false;\n return !!next.el || next._hasBody();\n }\n\n /** Removes the container once nothing is left in it. */\n private static _tidy() {\n if (Snackbar._container?.childElementCount === 0) Snackbar._removeContainer();\n }\n\n _animateIn() {\n this.el.style.display = '';\n this.el.style.opacity = '0';\n this.el.style.transform = 'translateY(24px)';\n this.el.style.transition = `\n transform ${this.options.inDuration}ms ease,\n opacity ${this.options.inDuration}ms ease\n `;\n this._transitionTimer = setTimeout(() => {\n this.el.style.transform = '';\n this.el.style.opacity = '1';\n }, 1);\n }\n\n /**\n * Arm the dismissal timer.\n *\n * One timeout, not a 20ms interval ticking a counter down: the old form woke\n * the page up 50 times a second per snackbar purely to subtract 20 from a\n * number. Dragging pauses the countdown via _pauseTimer/_resumeTimer instead.\n */\n _setTimer() {\n if (this.timeRemaining === Infinity) return;\n this._deadline = Date.now() + this.timeRemaining;\n this.counterTimeout = setTimeout(() => this.dismiss(), this.timeRemaining);\n }\n\n /** Stop the countdown, banking the time that was left on it. */\n _pauseTimer() {\n if (this.counterTimeout == null) return;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this.timeRemaining = Math.max(0, this._deadline - Date.now());\n }\n\n /** Restart a countdown stopped by {@link _pauseTimer}. */\n _resumeTimer() {\n if (this._dismissed || this.panning || this.el.matches(':hover, :focus-within') || this.counterTimeout != null) return;\n this._setTimer();\n }\n\n private _restoreFocus(remove = false) {\n const focused = (this.el.getRootNode() as Document | ShadowRoot).activeElement;\n const returnFocus = focused && this.el.contains(focused) ? this._returnFocus : null;\n this.el.inert = true;\n if (remove) this._remove(false);\n if (returnFocus?.isConnected) returnFocus.focus({ preventScroll: true });\n }\n\n /**\n * Dismiss snackbar with animation.\n */\n dismiss() {\n if (this._leaveQueue()) return;\n this._dismissed = true;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this._restoreFocus();\n if (this._events.signal.aborted) return;\n Utils.emit(this.el, 'close');\n const duration = this.options.outDuration;\n const transitions = [`margin ${duration}ms ease`, `opacity ${duration}ms ease`];\n\n if (this.wasSwiped) {\n // Carry on off the side the user swiped toward, from where they let go.\n const direction = this.xPos < this.startingXPos ? -1 : 1;\n this.el.style.transform = `translateX(${direction * this.el.offsetWidth}px)`;\n this.el.style.opacity = '0';\n transitions.push(`transform ${duration}ms ease`);\n }\n\n this.el.style.transition = transitions.join(', ');\n\n clearTimeout(this._transitionTimer);\n this._transitionTimer = setTimeout(() => {\n this.el.style.opacity = '0';\n this.el.style.marginTop = '-40px';\n }, 1);\n\n this._dismissTimer = setTimeout(() => {\n // While the snackbar is still in the page, so the event reaches the document.\n Utils.emit(this.el, 'closed');\n this._remove();\n // Call the optional callback\n if (typeof this.options.completeCallback === 'function') {\n this.options.completeCallback();\n }\n }, this.options.outDuration);\n }\n\n static {\n Snackbar._snackbars = [];\n Snackbar._queue = [];\n Snackbar._container = null;\n Snackbar._draggedSnackbar = null;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/tabs.ts"],
4
- "sourcesContent": ["import { Component, BaseOptions } from '../core/component';\nimport { Utils, restoreAttribute } from '../core/utils';\n\nexport interface TabsOptions extends BaseOptions {\n /**\n * Indicator transition duration in milliseconds, on an ease-out curve. The\n * default, null, follows the --md-comp-tabs-indicator-duration and\n * --md-comp-tabs-indicator-easing spring tokens instead.\n * @default null\n */\n duration: number | null;\n /**\n * Callback for when a new tab content is shown.\n * @default null\n */\n onShow: (newContent: Element) => void;\n /**\n * Set to true to swipe between panels. The panels move into a full-width\n * scroll-snap track, so touch and trackpad swipes are native scrolling.\n * This also uses the responsiveThreshold option.\n * @default false\n */\n swipeable: boolean;\n /**\n * The maximum width of the screen, in pixels,\n * where the swipeable functionality initializes.\n * @default infinity\n */\n responsiveThreshold: number;\n}\n\n/** Left and Right move between tabs the way they point, so they swap in RTL. */\nconst STEPS = { ltr: { ArrowLeft: -1, ArrowRight: 1 }, rtl: { ArrowLeft: 1, ArrowRight: -1 } };\n\nconst _defaults: TabsOptions = {\n duration: null,\n onShow: null,\n swipeable: false,\n responsiveThreshold: Infinity // breakpoint for swipeable\n};\n\nconst scrollBehavior = (): ScrollBehavior =>\n window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth';\n\n/** Links cannot be :disabled; a tab is turned off with a class or aria-disabled. */\nconst isDisabled = (a: Element) => a.matches('.disabled, [aria-disabled=\"true\"]');\n\n/** Shown, as far as the browser can say; a responsive utility may hide a tab. */\nconst isShown = (a: Element) => a.checkVisibility?.() ?? true;\n\n/** A tab the keyboard can reach: enabled and shown. */\nconst isUsable = (a: Element) => !isDisabled(a) && isShown(a);\n\nexport class Tabs extends Component<TabsOptions> {\n _tabLinks: NodeListOf<HTMLAnchorElement>;\n _index: number;\n _indicator: HTMLElement;\n _tabWidth: number;\n _tabsWidth: number;\n _track: HTMLElement;\n private _panels: HTMLElement[] = [];\n // The panel a programmatic scroll is heading for. Scroll events on the way\n // there pass over other panels and must not select them.\n private _scrollTarget: number | null = null;\n private _scrollTimer: ReturnType<typeof setTimeout>;\n private _trackObserver: ResizeObserver | null = null;\n private _trackWidth = -1;\n _activeTabLink: HTMLAnchorElement;\n _content: HTMLElement;\n private _originalPanels = new Map<HTMLElement, { display: string; priority: string; active: boolean; inert: boolean; marker?: Comment }>();\n private _originalLinks = new Map<HTMLAnchorElement, { active: boolean; current: string | null; selected: string | null; tabindex: string | null }>();\n /**\n * Whether the page made the strip a tablist. The roles are the author's;\n * in that mode the component keeps aria-selected and a roving tabindex, and\n * the arrow keys select as they move, as the ARIA tabs pattern asks.\n */\n private _tablist = false;\n /** The bar's own tabindex as the page wrote it, put back on destroy. */\n private _barTabindex: string | null = null;\n /** Re-chooses a tablist's Tab stop when the strip is shown, hidden or resized. */\n private _stripObserver: ResizeObserver | null = null;\n\n constructor(el: HTMLElement, options: Partial<TabsOptions>) {\n super(el, options);\n\n this._tabLinks = this._queryTabLinks();\n if (!this._tabLinks.length) {\n console.error('Tabs: no tab links (an <a> child) to show');\n return;\n }\n this._setupTablist();\n this._tabLinks.forEach(link => {\n this._originalLinks.set(link, {\n active: link.classList.contains('active'), current: link.getAttribute('aria-current'),\n selected: link.getAttribute('aria-selected'), tabindex: link.getAttribute('tabindex')\n });\n const panel = this._panelFor(link);\n if (panel) this._originalPanels.set(panel, {\n display: panel.style.display, priority: panel.style.getPropertyPriority('display'),\n active: panel.classList.contains('active'), inert: panel.inert\n });\n });\n // Swiping needs at least one panel the links resolve to.\n this.options.swipeable &&= window.innerWidth <= this.options.responsiveThreshold && this._originalPanels.size > 0;\n this._index = 0;\n this._setupActiveTabLink();\n if (this.options.swipeable) {\n this._setupSwipeableTabs();\n } else {\n this._setupNormalTabs();\n }\n // Setup tabs indicator after content to ensure accurate widths\n this._setTabsAndTabWidth();\n this._createIndicator();\n this._setupEventHandlers();\n // Labels measured before a web font arrives have the fallback's width,\n // and the strip's size need not change when the font arrives.\n document.fonts?.ready.then(() => {\n if (this.el['Expressive_Tabs'] === this) this._remeasure();\n });\n }\n\n private _setupTablist() {\n this._tablist = this.el.getAttribute('role') === 'tablist';\n // Firefox makes an overflowing bar a Tab stop of its own, ahead of the\n // tabs; a tablist is one Tab stop, so the bar steps aside.\n this._barTabindex = this.el.getAttribute('tabindex');\n if (this._tablist) this.el.tabIndex = -1;\n // A strip set up inside a closed dialog has no visible tabs yet; opening\n // it changes the strip's size, and so does a window resize or a utility\n // that shows or hides a tab. The tabs are watched too: at the 840px\n // breakpoint they switch between equal and intrinsic widths inside a\n // strip that may keep its size. Each change re-measures the indicator,\n // and a tablist chooses its Tab stop again.\n this._stripObserver = new ResizeObserver(() => {\n if (this._tablist) this._refreshTabStop();\n this._remeasure();\n });\n this._stripObserver.observe(this.el);\n this._tabLinks.forEach((a) => this._stripObserver.observe(a));\n }\n\n static get defaults(): TabsOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Tabs';\n\n destroy() {\n this._stripObserver?.disconnect();\n this._stripObserver = null;\n this._indicator?.remove();\n if (this._track) {\n this._teardownSwipeableTabs();\n }\n this._originalPanels.forEach((original, panel) => {\n panel.style.setProperty('display', original.display, original.priority);\n panel.classList.toggle('active', original.active);\n panel.inert = original.inert;\n if (!panel.className) panel.removeAttribute('class');\n });\n this._originalLinks.forEach((original, link) => {\n link.classList.toggle('active', original.active);\n restoreAttribute(link, 'aria-current', original.current);\n restoreAttribute(link, 'aria-selected', original.selected);\n restoreAttribute(link, 'tabindex', original.tabindex);\n });\n restoreAttribute(this.el, 'tabindex', this._barTabindex);\n super.destroy();\n }\n\n /**\n * The index of tab that is currently shown.\n */\n get index() {\n return this._index;\n }\n\n _setupEventHandlers() {\n this.el.addEventListener('click', this._handleTabClick, { signal: this._events.signal });\n this.el.addEventListener('keydown', this._handleKeydown, { signal: this._events.signal });\n }\n\n /**\n * Left and Right move focus to the next tab, wrapping at the ends, and\n * Home and End to the first and last; disabled tabs are skipped. In link\n * tabs focus moves without choosing, and Enter follows the link. In a\n * tablist the tab that takes focus is selected too, the ARIA pattern's\n * automatic activation, since a panel here shows at once.\n */\n _handleKeydown = (e: KeyboardEvent) => {\n const steps = STEPS[getComputedStyle(this.el).direction === 'rtl' ? 'rtl' : 'ltr'];\n const target = Utils.focusTarget(Array.from(this._tabLinks).filter(isShown), e, steps, true) as HTMLAnchorElement | undefined;\n if (!target) return;\n e.preventDefault();\n target.focus();\n this._followFocus(target);\n };\n\n /**\n * In a tablist the tab that takes focus is selected; link tabs wait for\n * Enter. The page's focus handlers run inside focus(), and one may have\n * destroyed or replaced the tabs, which then are no longer this instance's.\n */\n private _followFocus(tab: HTMLAnchorElement) {\n if (this._tablist && tab !== this._activeTabLink && Tabs.getInstance(this.el) === this) this._select(tab);\n }\n\n private _remeasure() {\n this._setTabsAndTabWidth();\n if (this._tabWidth !== 0 && this._tabsWidth !== 0) this._positionIndicator();\n }\n\n _queryTabLinks() {\n return this.el.querySelectorAll<HTMLAnchorElement>(':scope > a');\n }\n\n _handleTabClick = (e: MouseEvent) => {\n const target = e.target as Element | null;\n if (!target) return;\n const tabLink = target.closest('a');\n if (!tabLink || !Array.from(this._tabLinks).includes(tabLink)) return;\n\n const disabled =\n tabLink.classList.contains('disabled') ||\n tabLink.getAttribute('aria-disabled') === 'true';\n if (disabled) {\n e.preventDefault();\n return;\n }\n // Act as regular link if target attribute is specified.\n if (tabLink.hasAttribute('target')) return;\n e.preventDefault();\n this._select(tabLink);\n };\n\n private _select(tabLink: HTMLAnchorElement) {\n if (this.options.swipeable) this._clickSwipeable(tabLink);\n else this._clickTab(tabLink);\n }\n\n private _clickSwipeable(tabLink: HTMLAnchorElement) {\n if (!this._panels.includes(this._panelFor(tabLink))) return;\n // A listener may destroy the tabs or pick another one.\n if (tabLink !== this._activeTabLink && !this._showPanel(tabLink)) return;\n this._scrollToActivePanel(scrollBehavior());\n }\n\n private _clickTab(tabLink: HTMLAnchorElement) {\n const oldContent = this._content;\n this._tabLinks = this._queryTabLinks();\n // Moves the class and aria-current together, off the old tab and onto this\n // one - they used to be able to disagree.\n const prevIndex = this._index;\n this._setActiveTabLink(tabLink);\n // A listener may destroy the tabs or pick another one.\n if (this._content && !this._swapPanels(oldContent)) return;\n // Update widths after content is swapped (scrollbar bugfix)\n this._setTabsAndTabWidth();\n this._animateIndicator(prevIndex);\n }\n\n /** Shows the active panel, hides the old one, then reports the change. */\n private _swapPanels(oldContent: HTMLElement | null): boolean {\n // Clear the hide rather than force 'block', so a flex or grid panel\n // keeps the display its stylesheet gives it.\n this._content.style.display = '';\n this._content.classList.add('active');\n if (oldContent && oldContent !== this._content) {\n oldContent.style.display = 'none';\n oldContent.classList.remove('active');\n }\n return this._notifyShow();\n }\n\n _createIndicator() {\n const indicator = document.createElement('span');\n indicator.classList.add('indicator');\n this.el.appendChild(indicator);\n this._indicator = indicator;\n this._positionIndicator();\n }\n\n /** Reads both positions before writing either. */\n private _positionIndicator() {\n const left = this._calcLeftPos(this._activeTabLink);\n const right = this._calcRightPos(this._activeTabLink);\n this._indicator.style.left = left + 'px';\n this._indicator.style.right = right + 'px';\n }\n\n /** The panel a link shows, or null for a `target` link or one without a hash. */\n private _panelFor(a: HTMLAnchorElement): HTMLElement | null {\n if (!a.hash || a.hasAttribute('target')) return null;\n // Looked up in the tabs' own root, so panels inside a shadow root resolve.\n return Utils.getElementById(this.el, Tabs._decodeHash(a.hash));\n }\n\n /**\n * The id a hash names. `a.hash` and `location.hash` come back\n * percent-encoded, so a non-ASCII id would never match without this. A\n * malformed escape throws, and is then taken as written.\n */\n private static _decodeHash(hash: string): string {\n try {\n return decodeURIComponent(hash.slice(1));\n } catch {\n return hash.slice(1);\n }\n }\n\n /**\n * Which tab is current, for the eye and for assistive technology.\n *\n * The class alone is a colour. Link tabs are navigation, so `aria-current`\n * is the part a screen reader reads. A strip the page made a tablist reads\n * `aria-selected` instead, with the keyboard model rule 2 asks of a\n * composite role. Either value changes as the user picks, which makes\n * keeping it the component's job, not the author's - see CONTEXT.md on\n * static semantics versus dynamic state. Writing it once in the markup and\n * never moving it left the old tab announcing itself as current.\n */\n private _setActiveTabLink(tabLink: HTMLAnchorElement, behavior: ScrollBehavior = scrollBehavior()) {\n const stop = this._tabStop(tabLink);\n Array.from(this._tabLinks).forEach(a => this._mark(a, a === tabLink, a === stop));\n this._activeTabLink = tabLink;\n this._index = Array.from(this._tabLinks).indexOf(tabLink);\n this._content = this._panelFor(tabLink);\n this._reveal(tabLink, behavior);\n }\n\n /** A tablist says selected and keeps one Tab stop; link tabs say current. */\n private _mark(a: HTMLAnchorElement, on: boolean, stop: boolean) {\n a.classList.toggle('active', on);\n if (this._tablist) {\n a.setAttribute('aria-selected', String(on));\n a.tabIndex = stop ? 0 : -1;\n } else if (on) a.setAttribute('aria-current', 'page');\n else a.removeAttribute('aria-current');\n }\n\n /**\n * The tablist's one Tab stop: the selected tab, or the first usable one\n * when the selected tab is disabled or hidden. The arrow keys skip both,\n * so a Tab stop on one would leave every other panel out of reach.\n */\n private _tabStop(selected: HTMLAnchorElement): HTMLAnchorElement {\n if (isUsable(selected)) return selected;\n // With nothing shown, as in a closed dialog, at least skip disabled tabs.\n const links = Array.from(this._tabLinks);\n return links.find(isUsable) ?? links.find((a) => !isDisabled(a)) ?? selected;\n }\n\n /** Showing or hiding the strip or a tab moves the Tab stop to a usable tab. */\n private _refreshTabStop() {\n const stop = this._tabStop(this._activeTabLink);\n this._tabLinks.forEach((a) => (a.tabIndex = a === stop ? 0 : -1));\n }\n\n /**\n * Scrolls an overflowing bar, and only the bar, so the tab is in view.\n * Measured as a visual offset, so it holds in a right-to-left bar too.\n */\n private _reveal(tab: HTMLElement, behavior: ScrollBehavior) {\n const bar = this.el.getBoundingClientRect();\n const box = tab.getBoundingClientRect();\n const left = Math.min(0, box.left - bar.left) || Math.max(0, box.right - bar.right);\n if (left) this.el.scrollBy({ left, behavior });\n }\n\n _setupActiveTabLink() {\n // If the location.hash matches one of the links, use that as the active tab.\n // If no match is found, use any with class 'active', then the first link.\n // Both sides decoded: an href may be written with or without escapes.\n const hash = location.hash && Tabs._decodeHash(location.hash);\n this._activeTabLink =\n Array.from(this._tabLinks).find(a => hash && Tabs._decodeHash(a.getAttribute('href') ?? '') === hash) ??\n this.el.querySelector<HTMLAnchorElement>('a.active') ??\n this._tabStop(this._tabLinks[0]);\n this._setActiveTabLink(this._activeTabLink, 'instant');\n\n this._originalPanels.forEach((_, panel) => panel.classList.toggle('active', panel === this._content));\n }\n\n _setupSwipeableTabs() {\n this._panels = [...new Set(Array.from(this._tabLinks, (a) => this._panelFor(a)).filter(Boolean))];\n const track = document.createElement('div');\n track.classList.add('tabs-content');\n this._panels[0].before(track);\n this._panels.forEach((panel) => {\n const marker = document.createComment('');\n panel.before(marker);\n this._originalPanels.get(panel).marker = marker;\n track.appendChild(panel);\n panel.style.display = '';\n });\n this._track = track;\n this._syncPanels();\n const options = { passive: true, signal: this._events.signal };\n track.addEventListener('scroll', this._handleTrackScroll, options);\n // A swipe or wheel that interrupts a programmatic scroll takes over from it.\n track.addEventListener('pointerdown', this._releaseScrollTarget, options);\n track.addEventListener('wheel', this._releaseScrollTarget, options);\n // A track that starts hidden (in a closed dialog or sheet) is 0px wide, so\n // the scroll below cannot reach the active panel. Re-align whenever the\n // track's width changes, which also covers window resizes. Only the width:\n // a panel growing taller mid-swipe must not pull the track back.\n this._trackObserver = new ResizeObserver(() => {\n if (track.clientWidth === this._trackWidth) return;\n this._trackWidth = track.clientWidth;\n this._scrollToActivePanel('instant');\n });\n this._trackObserver.observe(track);\n this._scrollToActivePanel('instant');\n }\n\n _teardownSwipeableTabs() {\n const track = this._track;\n this._trackObserver?.disconnect();\n this._trackObserver = null;\n this._releaseScrollTarget();\n this._originalPanels.forEach((original, panel) => original.marker?.replaceWith(panel));\n track.remove();\n this._track = undefined;\n }\n\n /** Only the shown panel is reachable; the others are off to the side. */\n private _syncPanels() {\n this._panels.forEach((panel) => {\n panel.classList.toggle('active', panel === this._content);\n panel.inert = panel !== this._content;\n });\n }\n\n /** The panel the track is mostly showing. Panels are exactly one track wide. */\n private _trackIndex() {\n return Math.round(Math.abs(this._track.scrollLeft) / (this._track.clientWidth || 1));\n }\n\n /**\n * Whether panel `index` fills the track. Compare positions, not rounded\n * indexes: a scroll still on its way to another panel can already round to\n * this one. Measured rather than computed from clientWidth, which rounds a\n * fractional track width, while the mandatory snap lands on the real edge.\n */\n private _trackAt(index: number) {\n return Math.abs(this._panels[index].getBoundingClientRect().left - this._track.getBoundingClientRect().left) < 1;\n }\n\n private _scrollToActivePanel(behavior: ScrollBehavior) {\n const index = this._panels.indexOf(this._content);\n if (index < 0 || this._trackAt(index)) return;\n // scrollLeft runs negative in a right-to-left track.\n const sign = getComputedStyle(this._track).direction === 'rtl' ? -1 : 1;\n const left = sign * index * this._track.clientWidth;\n this._scrollTarget = index;\n this._waitForScroll();\n this._track.scrollTo({ left, behavior });\n }\n\n // A smooth scroll that something cut short never arrives, and on a busy page\n // one can also take a while to start. Once the track has been still for half\n // a second, jump to the selected panel. The selection stands: a swipe or\n // wheel that took over has already released the target, so the scroll\n // events that follow choose the panel. Every scroll event restarts the wait.\n private _waitForScroll() {\n clearTimeout(this._scrollTimer);\n this._scrollTimer = setTimeout(() => {\n this._releaseScrollTarget();\n this._scrollToActivePanel('instant');\n }, 500);\n }\n\n _releaseScrollTarget = () => {\n clearTimeout(this._scrollTimer);\n this._scrollTarget = null;\n };\n\n _handleTrackScroll = () => {\n if (this._scrollTarget !== null) {\n // Release on arrival. A smooth scroll still heading to the previous\n // selection rounds to the new target on its way past, and releasing\n // there let the rest of that scroll select the panel it was heading to.\n if (this._trackAt(this._scrollTarget)) this._releaseScrollTarget();\n else this._waitForScroll();\n return;\n }\n const panel = this._panels[this._trackIndex()];\n if (!panel || panel === this._content) return;\n this._showPanel(Array.from(this._tabLinks).find((a) => this._panelFor(a) === panel));\n };\n\n private _showPanel(tabLink: HTMLAnchorElement): boolean {\n const prevIndex = this._index;\n this._setActiveTabLink(tabLink);\n this._syncPanels();\n this._setTabsAndTabWidth();\n this._animateIndicator(prevIndex);\n return this._notifyShow();\n }\n\n // After the old panel is hidden, so a listener sees one active panel.\n private _notifyShow(): boolean {\n const panel = this._content;\n return this._notify('change', this.options.onShow, { args: [panel], detail: { panel }, current: () => this._content === panel });\n }\n\n _setupNormalTabs() {\n // Hide Tabs Content\n Array.from(this._tabLinks).forEach((a) => {\n if (a === this._activeTabLink) return;\n const currContent = this._panelFor(a);\n if (currContent) currContent.style.display = 'none';\n });\n }\n\n _setTabsAndTabWidth() {\n this._tabsWidth = this.el.getBoundingClientRect().width;\n this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length;\n }\n\n _calcRightPos(el) {\n return Math.ceil(this._tabsWidth - el.offsetLeft - el.getBoundingClientRect().width);\n }\n\n _calcLeftPos(el) {\n return Math.floor(el.offsetLeft);\n }\n\n /**\n * Recalculate tab indicator position. This is useful when\n * the indicator position is not correct.\n */\n updateTabIndicator() {\n this._setTabsAndTabWidth();\n this._animateIndicator(this._index);\n }\n\n _animateIndicator(prevIndex) {\n // The trailing edge waits 30% of the move, so the bar stretches toward\n // the new tab before it shrinks. On the spring tokens that delay scales\n // with the spring and drops to 0 with it under reduced motion.\n const ms = this.options.duration;\n const timing = ms == null\n ? ['var(--md-comp-tabs-indicator-duration) var(--md-comp-tabs-indicator-easing)', 'calc(var(--md-comp-tabs-indicator-duration) * 0.3)']\n : [`${ms}ms ease-out`, `${ms * 0.3}ms`];\n const [leftDelay, rightDelay] = this._index - prevIndex >= 0 ? [timing[1], '0s'] : ['0s', timing[1]];\n this._indicator.style.transition = `left ${timing[0]} ${leftDelay}, right ${timing[0]} ${rightDelay}`;\n\n this._positionIndicator();\n }\n\n /**\n * Show tab content that corresponds to the tab with the id.\n * @param tabId The id of the tab that you want to switch to.\n */\n select(tabId: string) {\n const tab = Array.from(this._tabLinks).find(a => a.getAttribute('href') === '#' + tabId);\n if (tab) tab.click();\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/pieChart.ts"],
4
- "sourcesContent": ["import { LineChart, LineChartOptions, numberFormat, polarPoint as at, rowLegend, signs } from './lineChart';\nimport { svgNode as node } from '../core/utils';\n\nexport type PieChartOptions = LineChartOptions;\n\n// ponytail: rows past six repeat the colors; data-other groups the small ones.\nconst COLORS = 6;\n/** The pie's radius in a 100-unit box, leaving room for the active slice to grow. */\nconst RADIUS = 46;\n/** The active slice's scale, as in _pie-chart.scss. */\nconst GROWN = 1.06;\n/** Slices smaller than this share get no .values label. */\nconst LABEL_SHARE = 0.05;\nlet _maskId = 0;\n\n/** How many decimals a cell's number has, counting an exponent: \"2.5e-3\" has 4. */\nfunction decimals(text: string) {\n // Keeping only the number's characters first keeps the match linear.\n const [, fraction = '', exponent = '0'] = /(?:\\.(\\d+))?(?:e([+-]?\\d+))?$/i.exec(text.replace(/[^\\d.e+-]/gi, ''))!;\n return Math.max(0, fraction.length - Number(exponent));\n}\n\n/**\n * Sets each name's --pie-chart-name-top so neighbours on one side of the pie sit at least\n * --pie-chart-name-step apart, pushed away from the middle line: down below\n * it (`away` 1) and up above it (-1). Each top is the furthest of the natural\n * places of the names before it, plus a step for every name between. An\n * `anchor` is a fixed place before the first name, the unmoved innermost\n * name across the middle line.\n */\nfunction stack(names: [number, HTMLElement][], away: number, anchor?: number) {\n names.sort(([a], [b]) => (a - b) * away);\n const ys = names.map(([y]) => y);\n if (anchor !== undefined) ys.unshift(anchor);\n const first = ys.length - names.length;\n names.forEach(([, name], k) => {\n const tops = ys.slice(0, first + k + 1).map((y, j) =>\n `calc(50cqw + ${y} * var(--pie-chart-name-at) + ${(first + k - j) * away} * var(--pie-chart-name-step))`);\n name.style.setProperty('--pie-chart-name-top', `${away > 0 ? 'max' : 'min'}(${tops.join(', ')})`);\n });\n}\n\n/**\n * Pie chart. It reads its <table> like LineChart, but draws each row of the\n * first value column as a slice of the whole, clockwise from the top, with\n * a legend of every row and its share. With `.donut`, a <tfoot> row is the\n * total in the middle. Further columns show in the tooltip. With\n * `data-other`, rows under that percentage of the whole become one row,\n * last, named by `data-other-label` (\"Other\" by default); the table keeps\n * every row.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class PieChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** Each row's start and end, as fractions of a turn clockwise from the top. */\n private _turns: [number, number][];\n /** Each row's color, or undefined for a row with no slice. */\n private _colors: (string | undefined)[];\n private _slices: (SVGPathElement | null)[];\n /** Percent formatters by fraction digits, rebuilt once per legend. */\n private _percents: Intl.NumberFormat[];\n\n protected get _type() {\n return 'pie-chart';\n }\n\n /** A pie has no value axis. */\n protected get _axis() {\n return false;\n }\n\n protected get _points() {\n return false;\n }\n\n protected get _circular() {\n return true;\n }\n\n protected _read() {\n super._read();\n const small = this._small();\n if (!small) return;\n const sum = this.series[0].values.reduce<number>((total, value, i) => total + (small[i] ? Math.max(0, value!) : 0), 0);\n const text = this._written(sum, this._rows.filter((_, i) => small[i]).map((row) => row.cells[1]));\n const keep = <T>(list: T[], other: T) => [...list.filter((_, i) => !small[i]), other];\n this.labels = keep(this.labels, this.el.dataset.otherLabel || 'Other');\n // Only the first column adds up; further columns have no value for the group.\n this.series = this.series.map((series, i) => {\n const values = keep(series.values, i ? null : sum);\n return { ...series, values, tops: values, text: keep(series.text, i ? '' : text) };\n });\n }\n\n /**\n * The group's sum written like its cells: with their signs, and to their\n * decimals, or compact when data-value stands behind text such as \"$38M\".\n */\n private _written(sum: number, cells: HTMLTableCellElement[]) {\n const texts = cells.map((cell) => cell.textContent.trim());\n const [prefix, suffix] = signs(texts[0]);\n return `${prefix}${numberFormat(this.el, this._precision(texts, cells)).format(sum)}${suffix}`;\n }\n\n private _precision(texts: string[], cells: HTMLTableCellElement[]): Intl.NumberFormatOptions {\n if (cells.some((cell) => cell.dataset.value)) return { notation: 'compact', maximumSignificantDigits: 3 };\n const digits = Math.max(0, ...texts.map(decimals));\n // Older engines take at most 20 fraction digits; past that, keep the sum's first digits.\n return digits > 20 ? { maximumSignificantDigits: 3 } : { maximumFractionDigits: digits };\n }\n\n /**\n * Which rows data-other groups: those with a value under that percentage\n * of the whole. Null when it groups nothing, as one small row is clearer\n * by its own name.\n */\n private _small() {\n const percent = this._number('other');\n const values = this.series[0]?.values.map((value) => (value === null ? null : Math.max(0, value)));\n if (!values || !(percent! > 0)) return null;\n const total = values.reduce<number>((sum, value) => sum + (value ?? 0), 0);\n // A row exactly at the percentage stays, despite rounding in the division.\n const small = values.map((value) => value !== null && (value / total) * 100 < percent! - 1e-9);\n return small.filter(Boolean).length > 1 ? small : null;\n }\n\n static key = 'Expressive_PieChart';\n\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n super.show(index);\n this._slices.forEach((slice, i) => slice?.classList.toggle('active', i === index));\n // LineChart hides the tooltip for -1 and for an index past the last row.\n if (this._tooltip.hidden) return;\n\n const color = this._colors[index];\n this._tooltip.querySelectorAll<HTMLElement>('[data-series]').forEach((span) => {\n if (color) span.dataset.series = color;\n else delete span.dataset.series;\n });\n const share = this._share(index);\n const value = this._tooltip.querySelector('span:nth-of-type(2)');\n if (share && value) value.textContent += ` (${share})`;\n }\n\n /** CSS places the tooltip on the slice's middle from --turn. */\n protected _place(index: number) {\n const middle = (this._turns[index][0] + this._turns[index][1]) / 2;\n this._tooltip.style.setProperty('--turn', String(middle));\n // On the right half it opens leftwards, over the pie.\n this._tooltip.classList.toggle('end', middle < 0.5);\n }\n\n /** The row's share of the whole as a percentage, or '' for none. */\n private _share(index: number) {\n const [start, end] = this._turns[index];\n if (end <= start) return '';\n const share = end - start;\n // Whole percentages, with a tenth below 10% so a small part is not 0%.\n const digits = share < 0.1 ? 1 : 0;\n (this._percents ??= [])[digits] ??= this._percent(digits);\n return this._percents[digits].format(share);\n }\n\n private _percent(digits: number) {\n return numberFormat(this.el, { style: 'percent', maximumFractionDigits: digits });\n }\n\n // ponytail: names only move up or down their side, so many thin slices\n // near the top or bottom run into the caption or legend; group them as \"Other\".\n /**\n * Each slice's row name outside it, on the slice's middle, with a leader\n * line back to the slice. Names on the right half run rightwards and those\n * on the left run leftwards.\n */\n private _names() {\n const names = document.createElement('div');\n names.className = 'pie-chart-names';\n // Right above, right below, left above and left below the middle line.\n const sides: [number, HTMLElement][][] = [[], [], [], []];\n this._turns.forEach(([start, end], i) => {\n if (end <= start) return;\n const turn = (start + end) / 2;\n const y = -Math.cos(turn * 2 * Math.PI);\n const name = document.createElement('span');\n name.dataset.series = this._colors[i];\n name.style.setProperty('--turn', String(turn));\n name.classList.toggle('end', turn >= 0.5);\n // The text is cut short inside the name, which draws the leader line.\n const text = document.createElement('span');\n text.textContent = this.labels[i];\n name.append(text);\n names.append(name);\n sides[(turn >= 0.5 ? 2 : 0) + Number(y >= 0)].push([y, name]);\n });\n // Names below the line start a step under the innermost name above it.\n for (const i of [0, 2]) {\n stack(sides[i], -1);\n stack(sides[i + 1], 1, sides[i][0]?.[0]);\n }\n return names;\n }\n\n /** The legend: every row with its color, its cell and its share. */\n protected _guides(): Element[] {\n // A redraw picks up a changed lang attribute.\n this._percents = [];\n const text = this.series[0].text;\n return [rowLegend('pie-chart-legend', this._colors, this.labels.map((label, i) => [label, text[i], this._share(i)]))];\n }\n\n /** The row under the pointer by its angle from the middle, or -1 off the slices. */\n protected _indexAt(e: PointerEvent) {\n const [turn, share] = this._polarAt(e);\n // The distance in the SVG's 100-unit box.\n const distance = share * 100;\n const hole = this.el.classList.contains('donut')\n ? parseFloat(getComputedStyle(this.el).getPropertyValue('--md-comp-pie-chart-hole')) || 0\n : 0;\n if (distance < RADIUS * hole) return -1;\n const index = this._turns.findIndex(([start, end]) => start <= turn && turn < end);\n // The active slice is drawn larger, so the pointer stays on it to its edge.\n return distance > RADIUS * (index === this.activeIndex ? GROWN : 1) ? -1 : index;\n }\n\n /**\n * An SVG of slices in a -50 to 50 box, under a mask that cuts the gaps\n * between them and the donut's hole, which CSS sizes. The values and the\n * total are HTML over it.\n */\n protected _draw(): Element {\n const values = this.series[0].values.map((value) => Math.max(0, value ?? 0));\n const total = values.reduce((sum, value) => sum + value, 0);\n let turn = 0;\n this._turns = values.map((value) => [turn, (turn += total ? value / total : 0)]);\n // Colors go round the drawn slices; the last skips the first's color beside it.\n const drawn = this._turns.filter(([start, end]) => end > start);\n let slice = 0;\n this._colors = this._turns.map(([start, end]) => {\n if (end <= start) return undefined;\n const index = slice++;\n return String(index === drawn.length - 1 && index > 0 && index % COLORS === 0 ? 2 : (index % COLORS) + 1);\n });\n\n const pie = document.createElement('div');\n pie.className = 'pie-chart-pie';\n pie.setAttribute('aria-hidden', 'true');\n const svg = node('svg', { viewBox: '-50 -50 100 100', focusable: 'false' });\n const id = `pie-chart-mask-${++_maskId}`;\n const area = { x: '-50', y: '-50', width: '100', height: '100' };\n const mask = node('mask', { id, maskUnits: 'userSpaceOnUse', ...area });\n mask.append(\n node('rect', { ...area, fill: 'white' }),\n node('path', {\n class: 'pie-chart-gaps',\n stroke: 'black',\n d: drawn.length > 1 ? drawn.map(([start]) => `M0,0L${at(start, 50)}`).join('') : ''\n }),\n node('circle', { class: 'pie-chart-hole', r: String(RADIUS), fill: 'black' })\n );\n\n const slices = node('g', { mask: `url(#${id})` });\n const arc = `A${RADIUS},${RADIUS} 0`;\n this._slices = this._turns.map(([start, end], i) => {\n if (end <= start) return null;\n const slice = node('path', {\n class: 'pie-chart-slice',\n 'data-series': this._colors[i],\n // A whole circle is two half arcs; one arc cannot end where it starts.\n d: end - start >= 1\n ? `M0,${-RADIUS}${arc} 1 1 0,${RADIUS}${arc} 1 1 0,${-RADIUS}Z`\n : `M0,0L${at(start, RADIUS)}${arc} ${end - start > 0.5 ? 1 : 0} 1 ${at(end, RADIUS)}Z`\n }) as SVGPathElement;\n slices.append(slice);\n return slice;\n });\n svg.append(mask, slices);\n pie.append(svg, ...this._texts());\n\n const middle = this._total('pie-chart-total');\n if (middle) pie.append(middle);\n return pie;\n }\n\n /** The .values shares on the slices and the .labels names outside them. */\n private _texts(): Element[] {\n const texts: Element[] = [];\n if (this.el.classList.contains('values')) texts.push(this._values());\n if (this.el.classList.contains('labels') && !this.el.classList.contains('sparkline')) texts.push(this._names());\n return texts;\n }\n\n /** Each slice's share on it, except on slices too thin to hold it. */\n private _values() {\n const labels = document.createElement('div');\n labels.className = 'pie-chart-values';\n this._turns.forEach(([start, end], i) => {\n if (end - start < LABEL_SHARE) return;\n const label = document.createElement('span');\n label.dataset.series = this._colors[i];\n label.style.setProperty('--turn', String((start + end) / 2));\n label.textContent = this._share(i);\n labels.append(label);\n });\n return labels;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["slice"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/plugins/modalDisplayPlugin.ts"],
4
- "sourcesContent": ["import { DockedDisplayPlugin, DockedDisplayPluginOptions } from './dockedDisplayPlugin';\n\n/**\n * Shows a picker in a modal <dialog>, which the dialog styles draw as a\n * basic dialog over a scrim. The browser keeps focus inside it. Escape or a\n * press on the scrim closes it, and the picker hears that as Cancel; the\n * picker closes it itself through hide() on Ok or Cancel. Focus goes back\n * to the field that opened it.\n */\nexport class ModalDisplayPlugin {\n /** The fields that open the dialog, as DockedDisplayPlugin keeps them. */\n readonly triggers: HTMLElement[];\n private readonly dialog: HTMLDialogElement;\n private readonly onDismiss: () => void;\n /** Whether the picker, not the user, is closing the dialog. */\n private _settled = false;\n private _opener: HTMLElement | null = null;\n\n constructor(el: HTMLElement, container: HTMLElement, onDismiss: () => void) {\n this.triggers = [el];\n this.onDismiss = onDismiss;\n this.dialog = document.createElement('dialog');\n this.dialog.className = 'display-modal';\n const label = (el as HTMLInputElement).labels?.[0]?.textContent.trim() || el.getAttribute('aria-label');\n if (label) this.dialog.setAttribute('aria-label', label);\n this.dialog.append(container);\n el.parentElement.append(this.dialog);\n this.dialog.addEventListener('click', this._handleClick);\n this.dialog.addEventListener('close', this._handleClose);\n }\n\n /** The picker fills the dialog, so a press on the dialog itself is on the scrim. */\n private _handleClick = (e: MouseEvent) => {\n if (e.target === this.dialog) this.dialog.close();\n };\n\n private _handleClose = () => {\n const dismissed = !this._settled;\n this._settled = false;\n this._opener?.focus({ preventScroll: true });\n if (dismissed) this.onDismiss();\n };\n\n destroy = () => {\n this.dialog.removeEventListener('click', this._handleClick);\n this.dialog.removeEventListener('close', this._handleClose);\n this.dialog.remove();\n };\n\n show = () => {\n if (this.dialog.open) return;\n const root = this.dialog.getRootNode() as Document | ShadowRoot;\n this._opener = root.activeElement as HTMLElement | null;\n this.dialog.showModal();\n };\n\n hide = () => {\n if (!this.dialog.open) return;\n this._settled = true;\n this.dialog.close();\n };\n}\n\nexport type DisplayPlugin = DockedDisplayPlugin | ModalDisplayPlugin;\n\n/**\n * The display plugin a picker's `displayPlugin` option names: 'docked',\n * 'modal', or none for an inline picker. `onDismiss` is the picker's Cancel.\n */\nexport function createDisplayPlugin(\n type: string | null,\n el: HTMLElement,\n container: HTMLElement,\n options: Partial<DockedDisplayPluginOptions>,\n onDismiss: () => void\n): DisplayPlugin | undefined {\n if (type === 'modal') return new ModalDisplayPlugin(el, container, onDismiss);\n if (type === 'docked') return new DockedDisplayPlugin(el, container, options);\n return undefined;\n}\n\n/** Ok and Cancel close a modal picker; a docked one stays until a click outside. */\nexport function hideModal(plugin: DisplayPlugin | undefined) {\n if (plugin instanceof ModalDisplayPlugin) plugin.hide();\n}\n"],
5
- "mappings": ";;;;;AASO,IAAM,qBAAN,MAAyB;AAAA,EAS9B,YAAY,IAAiB,WAAwB,WAAuB;AAH5E;AAAA,SAAQ,WAAW;AACnB,SAAQ,UAA8B;AAgBtC;AAAA,SAAQ,eAAe,CAAC,MAAkB;AACxC,UAAI,EAAE,WAAW,KAAK,OAAQ,MAAK,OAAO,MAAM;AAAA,IAClD;AAEA,SAAQ,eAAe,MAAM;AAC3B,YAAM,YAAY,CAAC,KAAK;AACxB,WAAK,WAAW;AAChB,WAAK,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;AAC3C,UAAI,UAAW,MAAK,UAAU;AAAA,IAChC;AAEA,mBAAU,MAAM;AACd,WAAK,OAAO,oBAAoB,SAAS,KAAK,YAAY;AAC1D,WAAK,OAAO,oBAAoB,SAAS,KAAK,YAAY;AAC1D,WAAK,OAAO,OAAO;AAAA,IACrB;AAEA,gBAAO,MAAM;AACX,UAAI,KAAK,OAAO,KAAM;AACtB,YAAM,OAAO,KAAK,OAAO,YAAY;AACrC,WAAK,UAAU,KAAK;AACpB,WAAK,OAAO,UAAU;AAAA,IACxB;AAEA,gBAAO,MAAM;AACX,UAAI,CAAC,KAAK,OAAO,KAAM;AACvB,WAAK,WAAW;AAChB,WAAK,OAAO,MAAM;AAAA,IACpB;AAzCE,SAAK,WAAW,CAAC,EAAE;AACnB,SAAK,YAAY;AACjB,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,YAAY;AACxB,UAAM,QAAS,GAAwB,SAAS,CAAC,GAAG,YAAY,KAAK,KAAK,GAAG,aAAa,YAAY;AACtG,QAAI,MAAO,MAAK,OAAO,aAAa,cAAc,KAAK;AACvD,SAAK,OAAO,OAAO,SAAS;AAC5B,OAAG,cAAc,OAAO,KAAK,MAAM;AACnC,SAAK,OAAO,iBAAiB,SAAS,KAAK,YAAY;AACvD,SAAK,OAAO,iBAAiB,SAAS,KAAK,YAAY;AAAA,EACzD;AAgCF;AAQO,SAAS,oBACd,MACA,IACA,WACA,SACA,WAC2B;AAC3B,MAAI,SAAS,QAAS,QAAO,IAAI,mBAAmB,IAAI,WAAW,SAAS;AAC5E,MAAI,SAAS,SAAU,QAAO,IAAI,oBAAoB,IAAI,WAAW,OAAO;AAC5E,SAAO;AACT;AAGO,SAAS,UAAU,QAAmC;AAC3D,MAAI,kBAAkB,mBAAoB,QAAO,KAAK;AACxD;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/appBar.ts"],
4
- "sourcesContent": ["import { Component, BaseOptions } from '../core/component';\nimport { Utils, restoreAttribute } from '../core/utils';\n\nconst _defaults: BaseOptions = {};\n// Keys that open a full-screen search view from its field.\nconst OPEN_KEYS = ['Enter', 'ArrowDown'];\n\n/**\n * Collapse medium/large flexible app bars on scroll, and open the related\n * search view when the search field in a search app bar is selected.\n *\n * Observation is IntersectionObserver on a sentinel after the header.\n * A scroll listener would re-enter layout on every tick; this does not.\n */\nexport class AppBar extends Component<BaseOptions> {\n private _observer: IntersectionObserver | null = null;\n private _sentinel: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _view: HTMLElement | null = null;\n // The docked view's state before the first open, for destroy() to restore.\n private _restore: { hidden: HTMLElement['hidden']; expanded: string | null } | null = null;\n\n constructor(el: HTMLElement, options: Partial<BaseOptions>) {\n super(el, options);\n this._setupCollapse();\n this._setupSearch();\n }\n\n static get defaults(): BaseOptions {\n return _defaults;\n }\n\n static key = 'Expressive_AppBar';\n\n destroy() {\n this._observer?.disconnect();\n this._observer = null;\n this._sentinel?.remove();\n this._sentinel = null;\n if (this._restore) {\n this._view.hidden = this._restore.hidden;\n restoreAttribute(this._input, 'aria-expanded', this._restore.expanded);\n this._restore = null;\n }\n this.el.classList.remove('collapsed');\n super.destroy();\n }\n\n private _setupCollapse() {\n if (!this.el.classList.contains('medium') && !this.el.classList.contains('large')) {\n return;\n }\n // Collapsing shrinks the header, and scroll anchoring then scrolls the page\n // back by the height it lost. The sentinel follows the header, so it moves\n // with the page and that correction cannot bring it back into view. It sits\n // 64px, the small bar's height, above the header's bottom edge. An expanded\n // bar therefore collapses once the page has scrolled by the height that\n // collapsing removes, and a collapsed bar expands when the page is back at\n // its top. Zero height and no margins keep it out of the layout.\n this._sentinel = document.createElement('span');\n this._sentinel.setAttribute('aria-hidden', 'true');\n this._sentinel.style.cssText =\n 'display:block;height:0;position:relative;top:-64px;pointer-events:none;visibility:hidden';\n this.el.insertAdjacentElement('afterend', this._sentinel);\n this._observer = new IntersectionObserver(this._onIntersect);\n this._observer.observe(this._sentinel);\n }\n\n private _onIntersect = (entries: IntersectionObserverEntry[]) => {\n const entry = entries[0];\n if (!entry) return;\n // Collapse only when the sentinel has gone above the pinned header. A\n // sentinel below the viewport would move back into view as the bar shrank,\n // and the bar would switch sizes on every frame.\n this.el.classList.toggle(\n 'collapsed',\n !entry.isIntersecting && entry.boundingClientRect.top < this.el.getBoundingClientRect().top\n );\n };\n\n private _setupSearch() {\n this._input = this.el.querySelector('input[type=\"search\"]');\n if (!this._input) return;\n\n const id = this._input.getAttribute('aria-controls');\n this._view = (id && Utils.getElementById(this.el, id)) || this.el.querySelector('.search-view');\n if (!this._view) return;\n\n const { signal } = this._events;\n this._input.addEventListener('focus', this._onSearchFocus, { signal });\n this._input.addEventListener('click', this._openSearch, { signal });\n this._input.addEventListener('keydown', this._onSearchKeydown, { signal });\n }\n\n // A docked view opens on focus, like a combobox popup. A full-screen\n // dialog takes over the page, so reaching the field with Tab only focuses\n // it (WCAG 3.2.1); a click, Enter or ArrowDown opens it.\n private _onSearchFocus = () => {\n if (!(this._view instanceof HTMLDialogElement)) this._openSearch();\n };\n\n private _onSearchKeydown = (e: KeyboardEvent) => {\n if (!OPEN_KEYS.includes(e.key) || Utils.isComposing(e) || !(this._view instanceof HTMLDialogElement)) return;\n e.preventDefault();\n this._openSearch();\n };\n\n private _openSearch = () => {\n if (this._view instanceof HTMLDialogElement) {\n if (!this._view.open) this._view.showModal();\n return;\n }\n this._restore ??= { hidden: this._view.hidden, expanded: this._input.getAttribute('aria-expanded') };\n this._view.hidden = false;\n this._input.setAttribute('aria-expanded', 'true');\n };\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/ts/components/columnChart.ts"],
4
- "sourcesContent": ["import { LineChart, LineChartOptions, numberValue, Series } from './lineChart';\n\nexport type ColumnChartOptions = LineChartOptions;\n\n/**\n * A range cell's two ends, low first: data-value=\"12 28\", or text with an\n * en dash, a spaced hyphen or \"to\" between two numbers, such as \"$12\u2013$28\".\n * Anything else is a gap.\n */\nfunction rangeValue(cell: HTMLTableCellElement | undefined): [number | null, number | null] {\n const ends = rangeParts(cell).map(numberValue);\n return ends.length === 2 && !ends.includes(null)\n ? [Math.min(ends[0]!, ends[1]!), Math.max(ends[0]!, ends[1]!)]\n : [null, null];\n}\n\n/** A range cell's data-value split at spaces, or its text split between the ends. */\nfunction rangeParts(cell: HTMLTableCellElement | undefined): string[] {\n if (!cell) return [];\n return cell.dataset.value?.trim().split(/\\s+/) ?? cell.textContent.split(/\\s*[\u2013\u2014]\\s*|\\s+(?:-|to)\\s+/);\n}\n\n/** Clamps a value's distance down the plot to the plot. */\ntype Clamp = (value: number, y: (value: number) => number) => number;\n\n/** Where a series' column starts at a row: its stacked or range base, or zero. */\nconst baseAt = (series: Series, index: number) => series.base?.[index] ?? 0;\n\n/** A column's top and bottom insets, in percent, from its two ends. */\nfunction insets(from: number, to: number, y: (value: number) => number, clamp: Clamp): [number, number] {\n return [clamp(Math.max(from, to), y), 100 - clamp(Math.min(from, to), y)];\n}\n\n/**\n * Column chart. It reads its <table>, scales, labels and tooltip like\n * LineChart, but draws each row as a group of columns from zero, or one\n * column of segments with `stacked`. A series whose header has `range`\n * reads each cell as two ends and floats a column between them. Columns\n * are HTML clipped to their value, so their rounded corners keep their\n * shape at any size.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class ColumnChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** The `range` series, whose columns float. */\n private _ranges: Series[];\n\n protected get _type() {\n return 'column-chart';\n }\n\n protected get _fromZero() {\n return true;\n }\n\n protected get _points() {\n return false;\n }\n\n static key = 'Expressive_ColumnChart';\n\n /** A `range` series' low ends become its base; ranges do not stack. */\n protected _arrange(series: Series[]) {\n const ranges = (this._ranges = series.filter((each) => each.className.split(/\\s+/).includes('range')));\n for (const range of ranges) {\n const ends = this._rows.map((row) => rangeValue(row.cells[range.column]));\n range.base = ends.map(([low]) => low);\n range.values = range.tops = ends.map(([, high]) => high);\n }\n super._arrange(series.filter((each) => !ranges.includes(each)));\n }\n\n protected _draw(drawn = this.series): Element {\n const columns = document.createElement('div');\n columns.className = 'column-chart-columns';\n columns.setAttribute('aria-hidden', 'true');\n const clamp = (value: number, y = drawn[0]?.y ?? this._y) => Math.min(100, Math.max(0, y(value)));\n const stacked = this.el.classList.contains('stacked');\n // Columns grow from zero, or from the plot edge when zero is off the scale.\n const zero = clamp(0);\n columns.style.setProperty('--zero', `${zero}%`);\n this._plot.style.setProperty('--rows', String(this.labels.length));\n\n this.labels.forEach((_, index) => {\n const row = document.createElement('div');\n let below = zero;\n drawn.forEach((series) => {\n // A stacked segment above a gap has no known base, so it is left out.\n const to = series.tops[index];\n const from = baseAt(series, index);\n if (stacked && (to === null || from === null)) return;\n const column = document.createElement('span');\n // A gap in a grouped row keeps its empty slot, so the series stay aligned.\n if (to !== null) {\n column.className = series.className;\n column.dataset.series = series.color;\n // A stacked segment never hangs from zero, so it keeps the top rounding.\n column.classList.toggle('negative', !series.base && to < from);\n column.classList.toggle('floating', this._ranges.includes(series));\n const [top, bottom] = insets(from, to, series.y, clamp);\n column.style.setProperty('--top', `${top}%`);\n column.style.setProperty('--bottom', `${bottom}%`);\n below = this._start(column, series, index, below, clamp);\n // The cell text, which a bar chart with .values writes along its bar.\n if (this._horizontal) column.dataset.text = series.text[index];\n }\n row.append(column);\n });\n columns.append(row);\n });\n return columns;\n }\n\n /**\n * After update(), writes where a column grows from: its old ends, or for\n * a column new to the chart, the zero line or the segment below it in a\n * stack. Returns the next segment's start in a stack.\n * ponytail: in a stacked mixed chart a new end-scale column starts from\n * the start-scale stack; track `below` per scale if that matters.\n */\n private _start(column: HTMLElement, series: Series, index: number, below: number, clamp: Clamp): number {\n if (!this._before.length) return below;\n const [top, bottom] = this._oldInsets(series, index, clamp) ?? [below, 100 - below];\n column.style.setProperty('--from-top', `${top}%`);\n column.style.setProperty('--from-bottom', `${bottom}%`);\n return this.el.classList.contains('stacked') ? top : below;\n }\n\n /** A series' column at a row before update(), as its top and bottom insets, or null without one. */\n private _oldInsets(series: Series, index: number, clamp: Clamp): [number, number] | null {\n const old = this._before.find((each) => each.column === series.column);\n // A stacked or range base is unknown only where the top is too.\n const to = old?.tops[index] ?? null;\n return to === null ? null : insets(baseAt(old!, index), to, old!.y, clamp);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }