@expressivecss/expressive 0.15.0 → 0.16.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 (602) hide show
  1. package/CHANGELOG.md +1502 -1
  2. package/README.md +9 -8
  3. package/dist/css/expressive.css +19247 -11923
  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/fonts/LICENSE-noto-sans-arabic +93 -0
  8. package/dist/fonts/LICENSE-noto-sans-hebrew +93 -0
  9. package/dist/fonts/LICENSE-noto-sans-thai +93 -0
  10. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  11. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  12. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  13. package/dist/fonts/noto-sans-arabic-arabic-400.woff2 +0 -0
  14. package/dist/fonts/noto-sans-arabic-arabic-500.woff2 +0 -0
  15. package/dist/fonts/noto-sans-arabic-arabic-700.woff2 +0 -0
  16. package/dist/fonts/noto-sans-cyrillic-400.woff2 +0 -0
  17. package/dist/fonts/noto-sans-cyrillic-500.woff2 +0 -0
  18. package/dist/fonts/noto-sans-cyrillic-700.woff2 +0 -0
  19. package/dist/fonts/noto-sans-cyrillic-ext-400.woff2 +0 -0
  20. package/dist/fonts/noto-sans-cyrillic-ext-500.woff2 +0 -0
  21. package/dist/fonts/noto-sans-cyrillic-ext-700.woff2 +0 -0
  22. package/dist/fonts/noto-sans-devanagari-400.woff2 +0 -0
  23. package/dist/fonts/noto-sans-devanagari-500.woff2 +0 -0
  24. package/dist/fonts/noto-sans-devanagari-700.woff2 +0 -0
  25. package/dist/fonts/noto-sans-greek-400.woff2 +0 -0
  26. package/dist/fonts/noto-sans-greek-500.woff2 +0 -0
  27. package/dist/fonts/noto-sans-greek-700.woff2 +0 -0
  28. package/dist/fonts/noto-sans-greek-ext-400.woff2 +0 -0
  29. package/dist/fonts/noto-sans-greek-ext-500.woff2 +0 -0
  30. package/dist/fonts/noto-sans-greek-ext-700.woff2 +0 -0
  31. package/dist/fonts/noto-sans-hebrew-hebrew-400.woff2 +0 -0
  32. package/dist/fonts/noto-sans-hebrew-hebrew-500.woff2 +0 -0
  33. package/dist/fonts/noto-sans-hebrew-hebrew-700.woff2 +0 -0
  34. package/dist/fonts/noto-sans-latin-700.woff2 +0 -0
  35. package/dist/fonts/noto-sans-latin-ext-400.woff2 +0 -0
  36. package/dist/fonts/noto-sans-latin-ext-500.woff2 +0 -0
  37. package/dist/fonts/noto-sans-latin-ext-700.woff2 +0 -0
  38. package/dist/fonts/noto-sans-thai-thai-400.woff2 +0 -0
  39. package/dist/fonts/noto-sans-thai-thai-500.woff2 +0 -0
  40. package/dist/fonts/noto-sans-thai-thai-700.woff2 +0 -0
  41. package/dist/fonts/noto-sans-vietnamese-400.woff2 +0 -0
  42. package/dist/fonts/noto-sans-vietnamese-500.woff2 +0 -0
  43. package/dist/fonts/noto-sans-vietnamese-700.woff2 +0 -0
  44. package/dist/fonts/roboto-cyrillic-400.woff2 +0 -0
  45. package/dist/fonts/roboto-cyrillic-500.woff2 +0 -0
  46. package/dist/fonts/roboto-cyrillic-700.woff2 +0 -0
  47. package/dist/fonts/roboto-cyrillic-ext-400.woff2 +0 -0
  48. package/dist/fonts/roboto-cyrillic-ext-500.woff2 +0 -0
  49. package/dist/fonts/roboto-cyrillic-ext-700.woff2 +0 -0
  50. package/dist/fonts/roboto-greek-400.woff2 +0 -0
  51. package/dist/fonts/roboto-greek-500.woff2 +0 -0
  52. package/dist/fonts/roboto-greek-700.woff2 +0 -0
  53. package/dist/fonts/roboto-greek-ext-400.woff2 +0 -0
  54. package/dist/fonts/roboto-greek-ext-500.woff2 +0 -0
  55. package/dist/fonts/roboto-greek-ext-700.woff2 +0 -0
  56. package/dist/fonts/roboto-latin-700.woff2 +0 -0
  57. package/dist/fonts/roboto-latin-ext-400.woff2 +0 -0
  58. package/dist/fonts/roboto-latin-ext-500.woff2 +0 -0
  59. package/dist/fonts/roboto-latin-ext-700.woff2 +0 -0
  60. package/dist/fonts/roboto-vietnamese-400.woff2 +0 -0
  61. package/dist/fonts/roboto-vietnamese-500.woff2 +0 -0
  62. package/dist/fonts/roboto-vietnamese-700.woff2 +0 -0
  63. package/dist/js/chunks/chunk-2CS6TITK.mjs +219 -0
  64. package/dist/js/chunks/chunk-2CS6TITK.mjs.map +7 -0
  65. package/dist/js/chunks/chunk-2RLBDFH4.mjs +108 -0
  66. package/dist/js/chunks/chunk-2RLBDFH4.mjs.map +7 -0
  67. package/dist/js/chunks/chunk-3L3QIYLC.mjs +85 -0
  68. package/dist/js/chunks/chunk-3L3QIYLC.mjs.map +7 -0
  69. package/dist/js/chunks/chunk-4EWGD4V2.mjs +75 -0
  70. package/dist/js/chunks/chunk-4EWGD4V2.mjs.map +7 -0
  71. package/dist/js/chunks/chunk-4IKVPCSU.mjs +7 -0
  72. package/dist/js/chunks/chunk-4IKVPCSU.mjs.map +7 -0
  73. package/dist/js/chunks/chunk-4PIXLDNJ.mjs +127 -0
  74. package/dist/js/chunks/chunk-4PIXLDNJ.mjs.map +7 -0
  75. package/dist/js/chunks/{chunk-KVJAVDBC.mjs → chunk-4QUCNFSD.mjs} +64 -113
  76. package/dist/js/chunks/chunk-4QUCNFSD.mjs.map +7 -0
  77. package/dist/js/chunks/{chunk-UETTGDLI.mjs → chunk-4TRZ2AER.mjs} +35 -41
  78. package/dist/js/chunks/chunk-4TRZ2AER.mjs.map +7 -0
  79. package/dist/js/chunks/{chunk-C6CHEWYP.mjs → chunk-5KIHWJI2.mjs} +40 -26
  80. package/dist/js/chunks/chunk-5KIHWJI2.mjs.map +7 -0
  81. package/dist/js/chunks/{chunk-L27Q6ZMI.mjs → chunk-67ZPPKXS.mjs} +20 -33
  82. package/dist/js/chunks/chunk-67ZPPKXS.mjs.map +7 -0
  83. package/dist/js/chunks/{chunk-XAEAEHIX.mjs → chunk-6FSEUFVW.mjs} +39 -26
  84. package/dist/js/chunks/chunk-6FSEUFVW.mjs.map +7 -0
  85. package/dist/js/chunks/chunk-752ADW4M.mjs +225 -0
  86. package/dist/js/chunks/chunk-752ADW4M.mjs.map +7 -0
  87. package/dist/js/chunks/{chunk-CK2XCICY.mjs → chunk-75E5EDJF.mjs} +3 -11
  88. package/dist/js/chunks/chunk-75E5EDJF.mjs.map +7 -0
  89. package/dist/js/chunks/{chunk-KHXZ2A4K.mjs → chunk-7NLUI3RR.mjs} +139 -66
  90. package/dist/js/chunks/chunk-7NLUI3RR.mjs.map +7 -0
  91. package/dist/js/chunks/chunk-7W7TV6NY.mjs +108 -0
  92. package/dist/js/chunks/chunk-7W7TV6NY.mjs.map +7 -0
  93. package/dist/js/chunks/chunk-7YQBHTK3.mjs +225 -0
  94. package/dist/js/chunks/chunk-7YQBHTK3.mjs.map +7 -0
  95. package/dist/js/chunks/chunk-7YZ5CN3V.mjs +33 -0
  96. package/dist/js/chunks/chunk-7YZ5CN3V.mjs.map +7 -0
  97. package/dist/js/chunks/chunk-AI73GJKG.mjs +28 -0
  98. package/dist/js/chunks/chunk-AI73GJKG.mjs.map +7 -0
  99. package/dist/js/chunks/{chunk-LQWUDNHZ.mjs → chunk-ANKFWNWT.mjs} +21 -45
  100. package/dist/js/chunks/chunk-ANKFWNWT.mjs.map +7 -0
  101. package/dist/js/chunks/{chunk-5CEAOLUA.mjs → chunk-B7DQFHA5.mjs} +30 -47
  102. package/dist/js/chunks/chunk-B7DQFHA5.mjs.map +7 -0
  103. package/dist/js/chunks/chunk-BIGU5RCJ.mjs +153 -0
  104. package/dist/js/chunks/chunk-BIGU5RCJ.mjs.map +7 -0
  105. package/dist/js/chunks/{chunk-VGNYF6FB.mjs → chunk-BPF3I2MN.mjs} +109 -24
  106. package/dist/js/chunks/chunk-BPF3I2MN.mjs.map +7 -0
  107. package/dist/js/chunks/chunk-CMGXGYUC.mjs +74 -0
  108. package/dist/js/chunks/chunk-CMGXGYUC.mjs.map +7 -0
  109. package/dist/js/chunks/{chunk-NUHMOAOY.mjs → chunk-CSYWKEK3.mjs} +310 -196
  110. package/dist/js/chunks/chunk-CSYWKEK3.mjs.map +7 -0
  111. package/dist/js/chunks/chunk-CZSQHXEV.mjs +227 -0
  112. package/dist/js/chunks/chunk-CZSQHXEV.mjs.map +7 -0
  113. package/dist/js/chunks/chunk-DZYVU75J.mjs +121 -0
  114. package/dist/js/chunks/chunk-DZYVU75J.mjs.map +7 -0
  115. package/dist/js/chunks/{chunk-74MXKKLN.mjs → chunk-EC26RU2D.mjs} +11 -29
  116. package/dist/js/chunks/chunk-EC26RU2D.mjs.map +7 -0
  117. package/dist/js/chunks/{chunk-WDK4T63U.mjs → chunk-EVCVFEV3.mjs} +235 -146
  118. package/dist/js/chunks/chunk-EVCVFEV3.mjs.map +7 -0
  119. package/dist/js/chunks/chunk-FCNF4GRJ.mjs +445 -0
  120. package/dist/js/chunks/chunk-FCNF4GRJ.mjs.map +7 -0
  121. package/dist/js/chunks/chunk-GCWWEZKO.mjs +342 -0
  122. package/dist/js/chunks/chunk-GCWWEZKO.mjs.map +7 -0
  123. package/dist/js/chunks/chunk-GNRSYMVH.mjs +1 -0
  124. package/dist/js/chunks/chunk-GVZQH2H5.mjs +54 -0
  125. package/dist/js/chunks/chunk-GVZQH2H5.mjs.map +7 -0
  126. package/dist/js/chunks/chunk-GWZ76SR4.mjs +435 -0
  127. package/dist/js/chunks/chunk-GWZ76SR4.mjs.map +7 -0
  128. package/dist/js/chunks/{chunk-PDG64UHF.mjs → chunk-ILDRRG7T.mjs} +21 -23
  129. package/dist/js/chunks/chunk-ILDRRG7T.mjs.map +7 -0
  130. package/dist/js/chunks/chunk-INLZWHLY.mjs +80 -0
  131. package/dist/js/chunks/chunk-INLZWHLY.mjs.map +7 -0
  132. package/dist/js/chunks/chunk-JUKBBN6P.mjs +175 -0
  133. package/dist/js/chunks/chunk-JUKBBN6P.mjs.map +7 -0
  134. package/dist/js/chunks/chunk-KYIEG4U3.mjs +730 -0
  135. package/dist/js/chunks/chunk-KYIEG4U3.mjs.map +7 -0
  136. package/dist/js/chunks/{chunk-BGZLF6JZ.mjs → chunk-KZPSAXIU.mjs} +142 -32
  137. package/dist/js/chunks/chunk-KZPSAXIU.mjs.map +7 -0
  138. package/dist/js/chunks/chunk-LDXCC2L3.mjs +438 -0
  139. package/dist/js/chunks/chunk-LDXCC2L3.mjs.map +7 -0
  140. package/dist/js/chunks/chunk-NAC72P7R.mjs +137 -0
  141. package/dist/js/chunks/chunk-NAC72P7R.mjs.map +7 -0
  142. package/dist/js/chunks/chunk-NBJAUGPP.mjs +244 -0
  143. package/dist/js/chunks/chunk-NBJAUGPP.mjs.map +7 -0
  144. package/dist/js/chunks/chunk-NNHVANQA.mjs +113 -0
  145. package/dist/js/chunks/chunk-NNHVANQA.mjs.map +7 -0
  146. package/dist/js/chunks/chunk-NVQ5EHCU.mjs +376 -0
  147. package/dist/js/chunks/chunk-NVQ5EHCU.mjs.map +7 -0
  148. package/dist/js/chunks/{chunk-DXGRXYYL.mjs → chunk-OP43LLIC.mjs} +28 -45
  149. package/dist/js/chunks/chunk-OP43LLIC.mjs.map +7 -0
  150. package/dist/js/chunks/chunk-OUCHKSAW.mjs +63 -0
  151. package/dist/js/chunks/chunk-OUCHKSAW.mjs.map +7 -0
  152. package/dist/js/chunks/{chunk-TSZYSW7F.mjs → chunk-OYNUDOHR.mjs} +19 -47
  153. package/dist/js/chunks/chunk-OYNUDOHR.mjs.map +7 -0
  154. package/dist/js/chunks/{chunk-UAZSDUVP.mjs → chunk-P6DRQ6KS.mjs} +36 -30
  155. package/dist/js/chunks/chunk-P6DRQ6KS.mjs.map +7 -0
  156. package/dist/js/chunks/chunk-PA7NU5AK.mjs +99 -0
  157. package/dist/js/chunks/chunk-PA7NU5AK.mjs.map +7 -0
  158. package/dist/js/chunks/chunk-QACZ6TUP.mjs +224 -0
  159. package/dist/js/chunks/chunk-QACZ6TUP.mjs.map +7 -0
  160. package/dist/js/chunks/{chunk-GJL6GCIU.mjs → chunk-QXKWVHBD.mjs} +265 -161
  161. package/dist/js/chunks/chunk-QXKWVHBD.mjs.map +7 -0
  162. package/dist/js/chunks/{chunk-X4ISMKE2.mjs → chunk-ROH2HDB4.mjs} +7 -6
  163. package/dist/js/chunks/chunk-ROH2HDB4.mjs.map +7 -0
  164. package/dist/js/chunks/chunk-S23RJ3XY.mjs +86 -0
  165. package/dist/js/chunks/chunk-S23RJ3XY.mjs.map +7 -0
  166. package/dist/js/chunks/{chunk-SMY7GJSS.mjs → chunk-SPPHF7YZ.mjs} +36 -29
  167. package/dist/js/chunks/chunk-SPPHF7YZ.mjs.map +7 -0
  168. package/dist/js/chunks/chunk-T3BNSRP3.mjs +152 -0
  169. package/dist/js/chunks/chunk-T3BNSRP3.mjs.map +7 -0
  170. package/dist/js/chunks/chunk-TFABTUAZ.mjs +108 -0
  171. package/dist/js/chunks/chunk-TFABTUAZ.mjs.map +7 -0
  172. package/dist/js/chunks/chunk-U4B3VHFS.mjs +507 -0
  173. package/dist/js/chunks/chunk-U4B3VHFS.mjs.map +7 -0
  174. package/dist/js/chunks/chunk-UGJHCHXG.mjs +341 -0
  175. package/dist/js/chunks/chunk-UGJHCHXG.mjs.map +7 -0
  176. package/dist/js/chunks/chunk-VFV75DHF.mjs +70 -0
  177. package/dist/js/chunks/chunk-VFV75DHF.mjs.map +7 -0
  178. package/dist/js/chunks/{chunk-ZX6M7SWO.mjs → chunk-VGY4M57S.mjs} +266 -120
  179. package/dist/js/chunks/chunk-VGY4M57S.mjs.map +7 -0
  180. package/dist/js/chunks/chunk-VH4BMAZS.mjs +167 -0
  181. package/dist/js/chunks/chunk-VH4BMAZS.mjs.map +7 -0
  182. package/dist/js/chunks/chunk-VJVQIXHC.mjs +123 -0
  183. package/dist/js/chunks/chunk-VJVQIXHC.mjs.map +7 -0
  184. package/dist/js/chunks/{chunk-SFI2U4YW.mjs → chunk-VMY55K2X.mjs} +76 -109
  185. package/dist/js/chunks/chunk-VMY55K2X.mjs.map +7 -0
  186. package/dist/js/chunks/{chunk-KUFHW3DS.mjs → chunk-VR3L2WN5.mjs} +11 -17
  187. package/dist/js/chunks/chunk-VR3L2WN5.mjs.map +7 -0
  188. package/dist/js/chunks/chunk-W6FAL3TI.mjs +38 -0
  189. package/dist/js/chunks/chunk-W6FAL3TI.mjs.map +7 -0
  190. package/dist/js/chunks/chunk-WU7XJ4RR.mjs +450 -0
  191. package/dist/js/chunks/chunk-WU7XJ4RR.mjs.map +7 -0
  192. package/dist/js/chunks/chunk-X7SDA2J5.mjs +116 -0
  193. package/dist/js/chunks/chunk-X7SDA2J5.mjs.map +7 -0
  194. package/dist/js/chunks/chunk-Y6H2X7ZC.mjs +209 -0
  195. package/dist/js/chunks/chunk-Y6H2X7ZC.mjs.map +7 -0
  196. package/dist/js/chunks/chunk-Y6TLRA3U.mjs +129 -0
  197. package/dist/js/chunks/chunk-Y6TLRA3U.mjs.map +7 -0
  198. package/dist/js/chunks/chunk-Z4GICXR2.mjs +190 -0
  199. package/dist/js/chunks/chunk-Z4GICXR2.mjs.map +7 -0
  200. package/dist/js/chunks/chunk-Z4OARDZ7.mjs +442 -0
  201. package/dist/js/chunks/chunk-Z4OARDZ7.mjs.map +7 -0
  202. package/dist/js/chunks/{chunk-FM5CZOUB.mjs → chunk-ZJNLAGY5.mjs} +19 -30
  203. package/dist/js/chunks/chunk-ZJNLAGY5.mjs.map +7 -0
  204. package/dist/js/chunks/chunk-ZKWUWBUB.mjs +81 -0
  205. package/dist/js/chunks/chunk-ZKWUWBUB.mjs.map +7 -0
  206. package/dist/js/chunks/chunk-ZM3XBHWV.mjs +746 -0
  207. package/dist/js/chunks/chunk-ZM3XBHWV.mjs.map +7 -0
  208. package/dist/js/chunks/chunk-ZO6ZLHFF.mjs +48 -0
  209. package/dist/js/chunks/chunk-ZO6ZLHFF.mjs.map +7 -0
  210. package/dist/js/chunks/chunk-ZVLOUDIJ.mjs +251 -0
  211. package/dist/js/chunks/chunk-ZVLOUDIJ.mjs.map +7 -0
  212. package/dist/js/expressive.cjs +10613 -4327
  213. package/dist/js/expressive.cjs.map +4 -4
  214. package/dist/js/expressive.js +10613 -4327
  215. package/dist/js/expressive.js.map +4 -4
  216. package/dist/js/expressive.min.js +23 -22
  217. package/dist/js/expressive.min.js.map +4 -4
  218. package/dist/js/expressive.mjs +182 -71
  219. package/dist/js/expressive.mjs.map +2 -2
  220. package/dist/js/internal/behaviors/bottomSheets.mjs +4 -3
  221. package/dist/js/internal/behaviors/copy.mjs +9 -0
  222. package/dist/js/internal/behaviors/copy.mjs.map +7 -0
  223. package/dist/js/internal/behaviors/dataTables.mjs +10 -0
  224. package/dist/js/internal/behaviors/dataTables.mjs.map +7 -0
  225. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  226. package/dist/js/internal/behaviors/forms.mjs +2 -2
  227. package/dist/js/internal/behaviors/imageCompare.mjs +8 -0
  228. package/dist/js/internal/behaviors/imageCompare.mjs.map +7 -0
  229. package/dist/js/internal/behaviors/lists.mjs +8 -0
  230. package/dist/js/internal/behaviors/lists.mjs.map +7 -0
  231. package/dist/js/internal/behaviors/paneResize.mjs +8 -0
  232. package/dist/js/internal/behaviors/paneResize.mjs.map +7 -0
  233. package/dist/js/internal/behaviors/sheetDrag.mjs +7 -2
  234. package/dist/js/internal/behaviors/sideSheets.mjs +4 -3
  235. package/dist/js/internal/behaviors/sortable.mjs +8 -0
  236. package/dist/js/internal/behaviors/sortable.mjs.map +7 -0
  237. package/dist/js/internal/behaviors/theme.mjs +8 -0
  238. package/dist/js/internal/behaviors/theme.mjs.map +7 -0
  239. package/dist/js/internal/behaviors/tour.mjs +8 -0
  240. package/dist/js/internal/behaviors/tour.mjs.map +7 -0
  241. package/dist/js/internal/behaviors/transferList.mjs +8 -0
  242. package/dist/js/internal/behaviors/transferList.mjs.map +7 -0
  243. package/dist/js/internal/components/appBar.mjs +3 -2
  244. package/dist/js/internal/components/autocomplete.mjs +4 -4
  245. package/dist/js/internal/components/backToTop.mjs +9 -0
  246. package/dist/js/internal/components/backToTop.mjs.map +7 -0
  247. package/dist/js/internal/components/barChart.mjs +5 -4
  248. package/dist/js/internal/components/buttonGroup.mjs +3 -2
  249. package/dist/js/internal/components/buttons.mjs +3 -3
  250. package/dist/js/internal/components/cards.mjs +3 -3
  251. package/dist/js/internal/components/carousel.mjs +3 -3
  252. package/dist/js/internal/components/cascader.mjs +10 -0
  253. package/dist/js/internal/components/cascader.mjs.map +7 -0
  254. package/dist/js/internal/components/characterCounter.mjs +3 -2
  255. package/dist/js/internal/components/chips.mjs +6 -5
  256. package/dist/js/internal/components/colorPicker.mjs +9 -0
  257. package/dist/js/internal/components/colorPicker.mjs.map +7 -0
  258. package/dist/js/internal/components/columnChart.mjs +4 -3
  259. package/dist/js/internal/components/commandPalette.mjs +3 -3
  260. package/dist/js/internal/components/confetti.mjs +3 -2
  261. package/dist/js/internal/components/currencyInput.mjs +9 -0
  262. package/dist/js/internal/components/currencyInput.mjs.map +7 -0
  263. package/dist/js/internal/components/datepicker.mjs +11 -8
  264. package/dist/js/internal/components/expandingCard.mjs +3 -3
  265. package/dist/js/internal/components/funnelChart.mjs +10 -0
  266. package/dist/js/internal/components/funnelChart.mjs.map +7 -0
  267. package/dist/js/internal/components/heatmapChart.mjs +4 -3
  268. package/dist/js/internal/components/hoverCard.mjs +9 -0
  269. package/dist/js/internal/components/hoverCard.mjs.map +7 -0
  270. package/dist/js/internal/components/index.mjs +131 -66
  271. package/dist/js/internal/components/inputMask.mjs +9 -0
  272. package/dist/js/internal/components/inputMask.mjs.map +7 -0
  273. package/dist/js/internal/components/keypad.mjs +3 -3
  274. package/dist/js/internal/components/lightbox.mjs +3 -3
  275. package/dist/js/internal/components/lineChart.mjs +25 -4
  276. package/dist/js/internal/components/loadingOverlay.mjs +9 -0
  277. package/dist/js/internal/components/loadingOverlay.mjs.map +7 -0
  278. package/dist/js/internal/components/mapView.mjs +3 -3
  279. package/dist/js/internal/components/menu.mjs +3 -3
  280. package/dist/js/internal/components/menubar.mjs +10 -0
  281. package/dist/js/internal/components/menubar.mjs.map +7 -0
  282. package/dist/js/internal/components/messageScroller.mjs +3 -3
  283. package/dist/js/internal/components/mixedChart.mjs +5 -4
  284. package/dist/js/internal/components/navigationRail.mjs +3 -2
  285. package/dist/js/internal/components/particles.mjs +3 -2
  286. package/dist/js/internal/components/pieChart.mjs +4 -3
  287. package/dist/js/internal/components/pullToRefresh.mjs +9 -0
  288. package/dist/js/internal/components/pullToRefresh.mjs.map +7 -0
  289. package/dist/js/internal/components/questionnaire.mjs +3 -3
  290. package/dist/js/internal/components/radarChart.mjs +4 -3
  291. package/dist/js/internal/components/radialChart.mjs +4 -3
  292. package/dist/js/internal/components/registry.mjs +59 -41
  293. package/dist/js/internal/components/richTextEditor.mjs +3 -3
  294. package/dist/js/internal/components/sankeyChart.mjs +10 -0
  295. package/dist/js/internal/components/sankeyChart.mjs.map +7 -0
  296. package/dist/js/internal/components/scatterChart.mjs +10 -0
  297. package/dist/js/internal/components/scatterChart.mjs.map +7 -0
  298. package/dist/js/internal/components/scrollspy.mjs +3 -2
  299. package/dist/js/internal/components/select.mjs +4 -4
  300. package/dist/js/internal/components/showMore.mjs +9 -0
  301. package/dist/js/internal/components/showMore.mjs.map +7 -0
  302. package/dist/js/internal/components/slider.mjs +3 -3
  303. package/dist/js/internal/components/snackbar.mjs +2 -2
  304. package/dist/js/internal/components/swipeActions.mjs +9 -0
  305. package/dist/js/internal/components/swipeActions.mjs.map +7 -0
  306. package/dist/js/internal/components/tabs.mjs +3 -4
  307. package/dist/js/internal/components/timepicker.mjs +5 -4
  308. package/dist/js/internal/components/tooltip.mjs +3 -3
  309. package/dist/js/internal/components/treeSelect.mjs +13 -0
  310. package/dist/js/internal/components/treeSelect.mjs.map +7 -0
  311. package/dist/js/internal/components/treemapChart.mjs +10 -0
  312. package/dist/js/internal/components/treemapChart.mjs.map +7 -0
  313. package/dist/js/internal/core/component.mjs +2 -1
  314. package/dist/js/internal/core/formControl.mjs +12 -0
  315. package/dist/js/internal/core/formControl.mjs.map +7 -0
  316. package/dist/js/internal/core/spring.mjs +11 -0
  317. package/dist/js/internal/core/spring.mjs.map +7 -0
  318. package/dist/js/internal/core/utils.mjs +11 -3
  319. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  320. package/dist/js/internal/plugins/modalDisplayPlugin.mjs +13 -0
  321. package/dist/js/internal/plugins/modalDisplayPlugin.mjs.map +7 -0
  322. package/dist/js/modular.mjs +173 -71
  323. package/dist/types/behaviors/bottomSheets.d.ts +19 -3
  324. package/dist/types/behaviors/copy.d.ts +18 -0
  325. package/dist/types/behaviors/dataTables.d.ts +129 -0
  326. package/dist/types/behaviors/dialogs.d.ts +27 -1
  327. package/dist/types/behaviors/forms.d.ts +68 -2
  328. package/dist/types/behaviors/imageCompare.d.ts +12 -0
  329. package/dist/types/behaviors/lists.d.ts +12 -0
  330. package/dist/types/behaviors/paneResize.d.ts +29 -0
  331. package/dist/types/behaviors/sheetDrag.d.ts +18 -0
  332. package/dist/types/behaviors/sideSheets.d.ts +1 -1
  333. package/dist/types/behaviors/sortable.d.ts +28 -0
  334. package/dist/types/behaviors/theme.d.ts +22 -0
  335. package/dist/types/behaviors/tour.d.ts +36 -0
  336. package/dist/types/behaviors/transferList.d.ts +51 -0
  337. package/dist/types/components/appBar.d.ts +5 -6
  338. package/dist/types/components/autocomplete.d.ts +91 -17
  339. package/dist/types/components/backToTop.d.ts +36 -0
  340. package/dist/types/components/barChart.d.ts +3 -6
  341. package/dist/types/components/buttonGroup.d.ts +2 -4
  342. package/dist/types/components/buttons.d.ts +5 -5
  343. package/dist/types/components/cards.d.ts +3 -16
  344. package/dist/types/components/carousel.d.ts +9 -15
  345. package/dist/types/components/cascader.d.ts +130 -0
  346. package/dist/types/components/characterCounter.d.ts +2 -15
  347. package/dist/types/components/chips.d.ts +65 -19
  348. package/dist/types/components/colorPicker.d.ts +42 -0
  349. package/dist/types/components/columnChart.d.ts +23 -10
  350. package/dist/types/components/commandPalette.d.ts +11 -16
  351. package/dist/types/components/confetti.d.ts +2 -4
  352. package/dist/types/components/currencyInput.d.ts +59 -0
  353. package/dist/types/components/datepicker.d.ts +56 -32
  354. package/dist/types/components/expandingCard.d.ts +4 -6
  355. package/dist/types/components/funnelChart.d.ts +38 -0
  356. package/dist/types/components/heatmapChart.d.ts +39 -8
  357. package/dist/types/components/hoverCard.d.ts +58 -0
  358. package/dist/types/components/index.d.ts +16 -1
  359. package/dist/types/components/inputMask.d.ts +30 -0
  360. package/dist/types/components/keypad.d.ts +38 -6
  361. package/dist/types/components/lightbox.d.ts +14 -20
  362. package/dist/types/components/lineChart.d.ts +172 -10
  363. package/dist/types/components/loadingOverlay.d.ts +42 -0
  364. package/dist/types/components/mapView.d.ts +26 -17
  365. package/dist/types/components/menu.d.ts +60 -22
  366. package/dist/types/components/menubar.d.ts +37 -0
  367. package/dist/types/components/messageScroller.d.ts +2 -14
  368. package/dist/types/components/mixedChart.d.ts +15 -6
  369. package/dist/types/components/navigationRail.d.ts +16 -5
  370. package/dist/types/components/particles.d.ts +8 -4
  371. package/dist/types/components/pieChart.d.ts +32 -7
  372. package/dist/types/components/pullToRefresh.d.ts +80 -0
  373. package/dist/types/components/questionnaire.d.ts +58 -16
  374. package/dist/types/components/radarChart.d.ts +10 -6
  375. package/dist/types/components/radialChart.d.ts +58 -7
  376. package/dist/types/components/registry.d.ts +73 -3
  377. package/dist/types/components/richTextEditor.d.ts +6 -14
  378. package/dist/types/components/sankeyChart.d.ts +72 -0
  379. package/dist/types/components/scatterChart.d.ts +102 -0
  380. package/dist/types/components/scrollspy.d.ts +3 -5
  381. package/dist/types/components/select.d.ts +43 -30
  382. package/dist/types/components/showMore.d.ts +51 -0
  383. package/dist/types/components/slider.d.ts +3 -15
  384. package/dist/types/components/snackbar.d.ts +61 -0
  385. package/dist/types/components/swipeActions.d.ts +81 -0
  386. package/dist/types/components/tabs.d.ts +89 -27
  387. package/dist/types/components/timepicker.d.ts +113 -21
  388. package/dist/types/components/tooltip.d.ts +56 -20
  389. package/dist/types/components/treeSelect.d.ts +106 -0
  390. package/dist/types/components/treemapChart.d.ts +56 -0
  391. package/dist/types/core/component.d.ts +43 -25
  392. package/dist/types/core/formControl.d.ts +21 -0
  393. package/dist/types/core/spring.d.ts +20 -0
  394. package/dist/types/core/utils.d.ts +85 -72
  395. package/dist/types/modular.d.ts +33 -1
  396. package/dist/types/plugins/dockedDisplayPlugin.d.ts +10 -8
  397. package/dist/types/plugins/modalDisplayPlugin.d.ts +32 -0
  398. package/package.json +10 -8
  399. package/src/sass/README.md +27 -18
  400. package/src/sass/abstracts/_elevation.scss +13 -7
  401. package/src/sass/abstracts/_index.scss +1 -0
  402. package/src/sass/abstracts/_mixins.scss +422 -36
  403. package/src/sass/abstracts/_spring.scss +63 -0
  404. package/src/sass/abstracts/_variables.scss +39 -21
  405. package/src/sass/base/_fonts.scss +61 -48
  406. package/src/sass/base/_global.scss +104 -24
  407. package/src/sass/base/_index.scss +2 -0
  408. package/src/sass/base/_normalize.scss +59 -114
  409. package/src/sass/base/_print.scss +21 -0
  410. package/src/sass/base/_prose.scss +68 -0
  411. package/src/sass/base/_typography.scss +9 -5
  412. package/src/sass/components/_accordion.scss +9 -16
  413. package/src/sass/components/_alert.scss +102 -0
  414. package/src/sass/components/_aura.scss +8 -3
  415. package/src/sass/components/_avatar.scss +3 -3
  416. package/src/sass/components/_back-to-top.scss +38 -0
  417. package/src/sass/components/_badges.scss +6 -5
  418. package/src/sass/components/_bar-chart.scss +41 -19
  419. package/src/sass/components/_bottom-sheet.scss +44 -16
  420. package/src/sass/components/_breadcrumb.scss +8 -1
  421. package/src/sass/components/_button-groups.scss +15 -25
  422. package/src/sass/components/_buttons.scss +156 -63
  423. package/src/sass/components/_calendar.scss +246 -0
  424. package/src/sass/components/_cards.scss +36 -44
  425. package/src/sass/components/_carousel.scss +27 -103
  426. package/src/sass/components/_cascader.scss +142 -0
  427. package/src/sass/components/_chips.scss +36 -46
  428. package/src/sass/components/_column-chart.scss +19 -12
  429. package/src/sass/components/_command-palette.scss +4 -7
  430. package/src/sass/components/_confetti.scss +0 -2
  431. package/src/sass/components/_countdown.scss +1 -1
  432. package/src/sass/components/_data-table.scss +162 -25
  433. package/src/sass/components/_datepicker.scss +54 -40
  434. package/src/sass/components/_description-list.scss +85 -0
  435. package/src/sass/components/_dialog.scss +42 -41
  436. package/src/sass/components/_docked-display.scss +1 -3
  437. package/src/sass/components/_drag-handle.scss +16 -20
  438. package/src/sass/components/_expanding-card.scss +20 -9
  439. package/src/sass/components/_fab-menu.scss +44 -32
  440. package/src/sass/components/_funnel-chart.scss +124 -0
  441. package/src/sass/components/_heatmap-chart.scss +111 -22
  442. package/src/sass/components/_icon-buttons.scss +7 -7
  443. package/src/sass/components/_icons-material-design.scss +2 -2
  444. package/src/sass/components/_image-compare.scss +108 -0
  445. package/src/sass/components/_index.scss +20 -0
  446. package/src/sass/components/_keypad.scss +39 -19
  447. package/src/sass/components/_kpi.scss +6 -11
  448. package/src/sass/components/_lightbox.scss +24 -13
  449. package/src/sass/components/_line-chart.scss +16 -2
  450. package/src/sass/components/_list.scss +59 -14
  451. package/src/sass/components/_loading-indicator.scss +1 -0
  452. package/src/sass/components/_loading-overlay.scss +105 -0
  453. package/src/sass/components/_map.scss +33 -11
  454. package/src/sass/components/_marquee.scss +3 -2
  455. package/src/sass/components/_mega-menu.scss +137 -0
  456. package/src/sass/components/_menu.scss +143 -123
  457. package/src/sass/components/_menubar.scss +59 -0
  458. package/src/sass/components/_message-scroller.scss +2 -2
  459. package/src/sass/components/_message.scss +3 -3
  460. package/src/sass/components/_mixed-chart.scss +37 -9
  461. package/src/sass/components/_modal-display.scss +21 -0
  462. package/src/sass/components/_navbar.scss +34 -20
  463. package/src/sass/components/_navigation-bar.scss +15 -77
  464. package/src/sass/components/_navigation-rail.scss +151 -92
  465. package/src/sass/components/_org-chart.scss +192 -0
  466. package/src/sass/components/_page-footer.scss +1 -1
  467. package/src/sass/components/_pagination.scss +6 -13
  468. package/src/sass/components/_panes.scss +32 -26
  469. package/src/sass/components/_particles.scss +0 -2
  470. package/src/sass/components/_pie-chart.scss +91 -11
  471. package/src/sass/components/_popover.scss +18 -5
  472. package/src/sass/components/_progress.scss +152 -31
  473. package/src/sass/components/_pull-to-refresh.scss +90 -0
  474. package/src/sass/components/_questionnaire.scss +74 -3
  475. package/src/sass/components/_radar-chart.scss +38 -10
  476. package/src/sass/components/_radial-chart.scss +113 -5
  477. package/src/sass/components/_rich-text-editor.scss +2 -2
  478. package/src/sass/components/_sankey-chart.scss +114 -0
  479. package/src/sass/components/_scatter-chart.scss +153 -0
  480. package/src/sass/components/_scrim.scss +0 -2
  481. package/src/sass/components/_scrollspy.scss +0 -2
  482. package/src/sass/components/_search.scss +26 -22
  483. package/src/sass/components/_show-more.scss +8 -0
  484. package/src/sass/components/_side-sheet.scss +23 -37
  485. package/src/sass/components/_skeleton.scss +2 -4
  486. package/src/sass/components/_snackbar.scss +27 -21
  487. package/src/sass/components/_split-button.scss +5 -5
  488. package/src/sass/components/_stat.scss +3 -8
  489. package/src/sass/components/_stepper.scss +1 -1
  490. package/src/sass/components/_swipe-actions.scss +71 -0
  491. package/src/sass/components/_tabs.scss +51 -32
  492. package/src/sass/components/_timeline.scss +12 -12
  493. package/src/sass/components/_timepicker.scss +109 -78
  494. package/src/sass/components/_toolbar.scss +35 -43
  495. package/src/sass/components/_tooltip.scss +21 -12
  496. package/src/sass/components/_tour.scss +89 -0
  497. package/src/sass/components/_transfer-list.scss +73 -0
  498. package/src/sass/components/_transitions.scss +4 -4
  499. package/src/sass/components/_tree.scss +3 -16
  500. package/src/sass/components/_treemap-chart.scss +122 -0
  501. package/src/sass/components/forms/_checkboxes.scss +106 -24
  502. package/src/sass/components/forms/_color-picker.scss +135 -0
  503. package/src/sass/components/forms/_color-swatches.scss +85 -0
  504. package/src/sass/components/forms/_drop-zone.scss +15 -9
  505. package/src/sass/components/forms/_fieldset.scss +7 -7
  506. package/src/sass/components/forms/_file-input.scss +6 -8
  507. package/src/sass/components/forms/_index.scss +3 -1
  508. package/src/sass/components/forms/_input-fields.scss +254 -90
  509. package/src/sass/components/forms/_radio-buttons.scss +33 -94
  510. package/src/sass/components/forms/_rating.scss +2 -32
  511. package/src/sass/components/forms/_select.scss +199 -20
  512. package/src/sass/components/forms/_slider.scss +91 -94
  513. package/src/sass/components/forms/_switches.scss +53 -164
  514. package/src/sass/custom.scss +10 -1
  515. package/src/sass/expressive.scss +3 -63
  516. package/src/sass/tokens/_contrast.scss +94 -0
  517. package/src/sass/tokens/_elevation.scss +16 -0
  518. package/src/sass/tokens/_index.scss +5 -0
  519. package/src/sass/tokens/_motion.scss +109 -0
  520. package/src/sass/tokens/_reference.scss +72 -141
  521. package/src/sass/tokens/_shape.scss +38 -0
  522. package/src/sass/tokens/_stacking.scss +27 -0
  523. package/src/sass/tokens/_state.scss +0 -2
  524. package/src/sass/tokens/_theme.scss +10 -1
  525. package/src/sass/tokens/_vibrant.scss +2 -5
  526. package/src/sass/utilities/_defer-render.scss +17 -0
  527. package/src/sass/utilities/_helpers.scss +183 -26
  528. package/src/sass/utilities/_index.scss +1 -0
  529. package/src/sass/utilities/_scroll-area.scss +0 -2
  530. package/src/sass/utilities/_spacing.scss +52 -34
  531. package/src/sass/utilities/_typescale.scss +8 -1
  532. package/src/sass/utilities/_visibility.scss +47 -76
  533. package/src/sass/utilities/_z-depth.scss +7 -4
  534. package/dist/js/chunks/chunk-33QVDDGR.mjs +0 -270
  535. package/dist/js/chunks/chunk-33QVDDGR.mjs.map +0 -7
  536. package/dist/js/chunks/chunk-45FER6RI.mjs +0 -59
  537. package/dist/js/chunks/chunk-45FER6RI.mjs.map +0 -7
  538. package/dist/js/chunks/chunk-5CEAOLUA.mjs.map +0 -7
  539. package/dist/js/chunks/chunk-6VATUZC6.mjs +0 -295
  540. package/dist/js/chunks/chunk-6VATUZC6.mjs.map +0 -7
  541. package/dist/js/chunks/chunk-74MXKKLN.mjs.map +0 -7
  542. package/dist/js/chunks/chunk-AIURVCG6.mjs +0 -55
  543. package/dist/js/chunks/chunk-AIURVCG6.mjs.map +0 -7
  544. package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +0 -7
  545. package/dist/js/chunks/chunk-C6CHEWYP.mjs.map +0 -7
  546. package/dist/js/chunks/chunk-CK2XCICY.mjs.map +0 -7
  547. package/dist/js/chunks/chunk-CXXM2L4F.mjs +0 -344
  548. package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +0 -7
  549. package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +0 -7
  550. package/dist/js/chunks/chunk-FM5CZOUB.mjs.map +0 -7
  551. package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +0 -7
  552. package/dist/js/chunks/chunk-K3HZMFMD.mjs +0 -135
  553. package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +0 -7
  554. package/dist/js/chunks/chunk-KHXZ2A4K.mjs.map +0 -7
  555. package/dist/js/chunks/chunk-KQACNQ22.mjs +0 -7
  556. package/dist/js/chunks/chunk-KQACNQ22.mjs.map +0 -7
  557. package/dist/js/chunks/chunk-KUFHW3DS.mjs.map +0 -7
  558. package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +0 -7
  559. package/dist/js/chunks/chunk-L27Q6ZMI.mjs.map +0 -7
  560. package/dist/js/chunks/chunk-LQWUDNHZ.mjs.map +0 -7
  561. package/dist/js/chunks/chunk-M372EDXD.mjs +0 -322
  562. package/dist/js/chunks/chunk-M372EDXD.mjs.map +0 -7
  563. package/dist/js/chunks/chunk-M3MURWMB.mjs +0 -82
  564. package/dist/js/chunks/chunk-M3MURWMB.mjs.map +0 -7
  565. package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +0 -7
  566. package/dist/js/chunks/chunk-OWG3LMUL.mjs +0 -169
  567. package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +0 -7
  568. package/dist/js/chunks/chunk-PD6HYHAE.mjs +0 -48
  569. package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +0 -7
  570. package/dist/js/chunks/chunk-PDG64UHF.mjs.map +0 -7
  571. package/dist/js/chunks/chunk-PO3AXVR3.mjs +0 -546
  572. package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +0 -7
  573. package/dist/js/chunks/chunk-QYGK36OG.mjs +0 -181
  574. package/dist/js/chunks/chunk-QYGK36OG.mjs.map +0 -7
  575. package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +0 -7
  576. package/dist/js/chunks/chunk-SMY7GJSS.mjs.map +0 -7
  577. package/dist/js/chunks/chunk-TCCA2HDG.mjs +0 -414
  578. package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +0 -7
  579. package/dist/js/chunks/chunk-TSZYSW7F.mjs.map +0 -7
  580. package/dist/js/chunks/chunk-UAZSDUVP.mjs.map +0 -7
  581. package/dist/js/chunks/chunk-UBRZZWRA.mjs +0 -127
  582. package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +0 -7
  583. package/dist/js/chunks/chunk-UCOE7ZDL.mjs +0 -287
  584. package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +0 -7
  585. package/dist/js/chunks/chunk-UETTGDLI.mjs.map +0 -7
  586. package/dist/js/chunks/chunk-UNCRDLP6.mjs +0 -136
  587. package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +0 -7
  588. package/dist/js/chunks/chunk-VGNYF6FB.mjs.map +0 -7
  589. package/dist/js/chunks/chunk-VGPGBNGL.mjs +0 -68
  590. package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +0 -7
  591. package/dist/js/chunks/chunk-VKAUVTQY.mjs +0 -1
  592. package/dist/js/chunks/chunk-VM4FTS7L.mjs +0 -48
  593. package/dist/js/chunks/chunk-VM4FTS7L.mjs.map +0 -7
  594. package/dist/js/chunks/chunk-WDK4T63U.mjs.map +0 -7
  595. package/dist/js/chunks/chunk-WOCCTVUF.mjs +0 -185
  596. package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +0 -7
  597. package/dist/js/chunks/chunk-WQYN5L4E.mjs +0 -107
  598. package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +0 -7
  599. package/dist/js/chunks/chunk-X4ISMKE2.mjs.map +0 -7
  600. package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +0 -7
  601. package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +0 -7
  602. /package/dist/js/chunks/{chunk-VKAUVTQY.mjs.map → chunk-GNRSYMVH.mjs.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/menu.ts"],
4
+ "sourcesContent": ["import { Utils, controllerFor, restoreAttribute } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\n// CSS anchor positioning, where the browser has it. A menu opened from its\n// trigger is anchored there and flips at the viewport edges in CSS; context\n// menus open at a point and cover-trigger menus overlap their trigger, so\n// both keep the measured placement, as do menus under a transformed\n// ancestor and every browser without anchors.\n// Either way the open menu is a manual popover in the top layer, so no\n// ancestor clips it or contains it, and its bounds are the viewport's.\n\n/** An element's parent, or its shadow root's host. */\nconst parentOf = (el: Element): Element | null => el.parentElement ?? ((el.getRootNode() as ShadowRoot).host || null);\n\n/**\n * Whether an ancestor of `el`, across shadow roots, moves it with a\n * transform. Firefox anchors a top-layer menu to the trigger's box as laid\n * out, before transforms, so a menu under one is measured instead, as in a\n * floating toolbar centred with `translateX(-50%)`.\n */\n// Computed values of the individual transform properties that move nothing,\n// such as a side sheet's resting `translate: 0px`.\nconst IDENTITY = { translate: /^(none|0px( 0px){0,2})$/, rotate: /^(none|(\\S+ )*0deg)$/, scale: /^(none|1( 1){0,2})$/ };\n\nfunction transformed(el: Element) {\n for (let node = parentOf(el); node; node = parentOf(node)) {\n const style = getComputedStyle(node);\n // An identity transform, often a translateZ(0) layer hint, moves nothing.\n if (!new DOMMatrixReadOnly(style.transform).isIdentity) return true;\n if (Object.entries(IDENTITY).some(([property, identity]) => !identity.test(style.getPropertyValue(property)))) return true;\n }\n return false;\n}\n\n/** The shadow roots an element sits in, nearest first. */\nfunction shadowRoots(el: Element) {\n const roots: ShadowRoot[] = [];\n for (let root = el.getRootNode(); 'host' in root; root = (root as ShadowRoot).host.getRootNode()) roots.push(root as ShadowRoot);\n return roots;\n}\n\n/**\n * The room a measured menu has in the viewport when aligned at each edge of\n * its trigger `el`. Aligned at `top` it starts `offset` below the trigger's\n * top edge, and at `bottom` it ends `offset` above its bottom edge. Negative\n * room means the menu does not fit that way.\n */\nfunction room(el: HTMLElement, menu: Pick<DOMRect, 'width' | 'height'>, offset: number) {\n const rect = el.getBoundingClientRect();\n return {\n left: window.innerWidth - (rect.left + menu.width),\n right: rect.right - menu.width,\n top: window.innerHeight - (rect.top + menu.height + offset),\n bottom: rect.bottom - (menu.height + offset)\n };\n}\n\n/** The keys that move between rows. Home and End go to the ends. */\nconst STEPS = { ArrowUp: -1, ArrowDown: 1 };\n// A list's rows: its own items, and the items of each <li role=\"none\"><ul\n// role=\"group\"> inside it.\nconst ROWS = ':scope > li, :scope > li > ul[role=\"group\"] > li';\n\nconst anchorSupported = typeof CSS !== 'undefined' && !!CSS.supports?.('anchor-name: --a');\n\n// The anchored inline properties, cleared together when the menu is reset.\nconst ANCHOR_STYLES = ['position', 'inset', 'max-height', 'position-anchor', 'position-area', 'position-try-fallbacks'];\n\nexport interface MenuOptions extends BaseOptions {\n /**\n * Defines the edge the menu is aligned to.\n * @default 'left'\n */\n alignment: 'left' | 'right';\n /**\n * If true, automatically focus menu el for keyboard.\n * @default true\n */\n autoFocus: boolean;\n /**\n * If true, constrainWidth to the size of the menu activator.\n *\n * A trigger narrower than the surface's own 112dp minimum cannot be\n * honoured, so such a menu is sized to its content instead - see\n * MIN_SURFACE_WIDTH.\n * @default true\n */\n constrainWidth: boolean;\n /**\n * Provide an element that will be the bounding container of the menu.\n * @default null\n */\n container: Element | ShadowRoot;\n /**\n * If false, the menu will show below the trigger.\n * That is the M3 placement. Pass `true` to cover the trigger.\n * @default false\n */\n coverTrigger: boolean;\n /**\n * The side of the trigger the menu opens on when there is room, such as\n * 'top' for a trigger in a bottom bar. It flips when there is not.\n * @default 'bottom'\n */\n placement: 'bottom' | 'top';\n /**\n * If true, close menu on item click.\n * @default true\n */\n closeOnClick: boolean;\n /**\n * If true, the menu will open on hover.\n * @default false\n */\n hover: boolean;\n /**\n * If true, the trigger is a region and the menu is its context menu: it\n * opens at the pointer on right-click, long-press or the keyboard context\n * menu key instead of on click. `data-context-menu` on the trigger sets it.\n * @default false\n */\n contextMenu: boolean;\n /**\n * The duration of the transition enter in milliseconds.\n * @default 150\n */\n inDuration: number;\n /**\n * The duration of the transition out in milliseconds.\n * @default 250\n */\n outDuration: number;\n /**\n * Function called when menu starts entering.\n * @default null\n */\n onOpenStart: (el: HTMLElement) => void;\n /**\n * Function called when menu finishes entering.\n * @default null\n */\n onOpenEnd: (el: HTMLElement) => void;\n /**\n * Function called when menu starts exiting.\n * @default null\n */\n onCloseStart: (el: HTMLElement) => void;\n /**\n * Function called when menu finishes exiting.\n * @default null\n */\n onCloseEnd: (el: HTMLElement) => void;\n /**\n * Function called when item is clicked.\n * @default null\n */\n onItemClick: (el: HTMLLIElement) => void;\n}\n\n// The menu surface's own width bounds, stated in `components/_menu.scss` and\n// restated here because the constraint below has to reason about them.\nconst MIN_SURFACE_WIDTH = 112;\nconst MAX_SURFACE_WIDTH = 280;\n\nconst _defaults: MenuOptions = {\n alignment: 'left',\n autoFocus: true,\n constrainWidth: true,\n container: null,\n coverTrigger: false,\n placement: 'bottom',\n closeOnClick: true,\n hover: false,\n contextMenu: false,\n inDuration: 150,\n outDuration: 250,\n onOpenStart: null,\n onOpenEnd: null,\n onCloseStart: null,\n onCloseEnd: null,\n onItemClick: null\n};\n\nconst SPACE = ' ';\n\nexport class Menu extends Component<MenuOptions> {\n static _menus: Menu[] = [];\n /** ID of the menu element. */\n id: string;\n /** The DOM element of the menu. */\n menuEl: HTMLElement;\n /** If the menu is open. */\n isOpen: boolean;\n /** If the menu content is scrollable. */\n isScrollable: boolean;\n isTouchMoving: boolean;\n /** The index of the item focused. */\n focusedIndex: number;\n filterQuery: string[];\n filterTimeout: ReturnType<typeof setTimeout>;\n private _pendingTimers = new Set<ReturnType<typeof setTimeout>>();\n private _transition = 0;\n /** Removes the listeners an open menu adds. */\n private _openEvents: AbortController | undefined;\n private _originalInert: string | null;\n private _menuClickTargets = new WeakMap<Event, HTMLElement>();\n // True while Space activates a row, so the click it sends can keep a radio\n // menu open.\n private _spaceActivation = false;\n /** Whether the pointer opened the menu, so opening leaves focus where it was. */\n private _openedByHover = false;\n /**\n * Viewport point the open context menu belongs to. Null outside a\n * right-click, so a keyboard or programmatic open uses the region's corner\n * rather than an old pointer position.\n */\n private _contextPoint: { x: number; y: number } | null = null;\n /** What had focus when a context menu opened; focus goes back there. */\n private _contextReturn: HTMLElement | null = null;\n\n constructor(el: HTMLElement, options: Partial<MenuOptions>) {\n super(el, { contextMenu: el.hasAttribute('data-context-menu'), ...options });\n\n Menu._menus.push(this);\n this.id = Utils.getIdFromTrigger(el);\n this.menuEl = Utils.getElementById(el, this.id);\n\n this.isOpen = false;\n this.isScrollable = false;\n this.isTouchMoving = false;\n this.focusedIndex = -1;\n this.filterQuery = [];\n // A context region is content, not a button: expanded, haspopup and\n // controls are not valid on it, and the menu key is how it is discovered.\n if (!this.options.contextMenu) {\n this.el.ariaExpanded = 'false';\n if (!this.el.hasAttribute('aria-haspopup')) this.el.setAttribute('aria-haspopup', 'menu');\n if (this.id && !this.el.hasAttribute('aria-controls'))\n this.el.setAttribute('aria-controls', this.id);\n }\n\n // Without a menu, moving it inserts a literal \"null\" text node and the\n // trigger's handlers would cancel its own clicks and keys to open nothing.\n if (!this.menuEl) {\n console.warn(`Menu skipped: no element matches target \"${this.id}\".`, el);\n return;\n }\n this._originalInert = this.menuEl.getAttribute('inert');\n // Keep the menu next to the trigger so positioning stays local.\n this._moveMenuToElement();\n this._setupAccessibility();\n this._makeMenuFocusable();\n this._setupSubmenus();\n this._setupEventHandlers();\n }\n\n static get defaults(): MenuOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Menu';\n\n destroy() {\n this._clearPendingTimers();\n this.isOpen = false;\n this._setExpanded(false);\n if (this.menuEl) Utils.setAnchorName(this.el, `--menu-${this.menuEl.id}`, false);\n clearTimeout(this.filterTimeout);\n this._resetMenuStyles();\n this._restoreInert();\n this._events.abort();\n this._openEvents?.abort();\n const index = Menu._menus.indexOf(this);\n if (index >= 0) Menu._menus.splice(index, 1);\n super.destroy();\n }\n\n _setupEventHandlers() {\n const { signal } = this._events;\n // Trigger keydown handler\n this.el.addEventListener('keydown', this._handleTriggerKeydown, { signal });\n // Item click handler\n this.menuEl?.addEventListener('click', this._handleMenuClick, { signal });\n if (this.menuEl?.querySelector(':scope > li > menu')) {\n this.menuEl.addEventListener('mouseover', this._handleSubmenuAlign, { signal });\n }\n if (this.options.contextMenu) {\n this.el.addEventListener('contextmenu', this._handleContextMenu, { signal });\n } else if (this.options.hover) {\n // Hover event handlers\n this.el.addEventListener('mouseenter', this._handleMouseEnter, { signal });\n this.el.addEventListener('mouseleave', this._handleMouseLeave, { signal });\n this.menuEl.addEventListener('mouseleave', this._handleMouseLeave, { signal });\n // Click event handlers\n } else {\n this.el.addEventListener('click', this._handleClick, { signal });\n }\n }\n\n _setupTemporaryEventHandlers() {\n this._openEvents?.abort();\n this._openEvents = controllerFor(this.el);\n const { signal } = this._openEvents;\n const passive = { passive: true, signal };\n document.addEventListener('click', this._handleDocumentClick, { signal });\n this.menuEl?.addEventListener('pointerdown', this._handleMenuPointerdown, passive);\n this.menuEl?.addEventListener('touchmove', this._handleDocumentTouchmove, passive);\n document.addEventListener('touchmove', this._handleDocumentTouchmove, passive);\n this.menuEl?.addEventListener('keydown', this._handleMenuKeydown, { signal });\n document.addEventListener('keydown', this._handleDocumentKeydown, { signal });\n window.addEventListener('resize', this._handleWindowResize, { signal });\n // A scroll inside a shadow root stays there, so each root around the\n // trigger is heard as well as the window.\n for (const target of [window, ...shadowRoots(this.el)]) {\n target.addEventListener('scroll', this._reanchor, { capture: true, passive: true, signal });\n }\n // A right-click elsewhere fires no click, so it would leave the menu open.\n if (this.options.contextMenu) document.addEventListener('contextmenu', this._handleDocumentContextMenu, { signal });\n }\n\n _handleContextMenu = (e: MouseEvent) => {\n // A nested region already answered this right-click; this one closes so\n // two menus never stack.\n if (e.defaultPrevented) {\n this.close();\n return;\n }\n // A right-click on another open menu inside this region belongs to that\n // menu, which keeps itself open.\n const path = e.composedPath();\n if (Menu._menus.some((menu) => menu !== this && menu.isOpen && path.includes(menu.menuEl))) return;\n e.preventDefault();\n if (!this.isOpen) {\n const root = this.el.getRootNode() as Document | ShadowRoot;\n this._contextReturn = root.activeElement instanceof HTMLElement ? root.activeElement : null;\n }\n // The menu key and Shift+F10 fire this too, with a point that may sit\n // outside the region (0, 0 in some engines). Those leave the point unset\n // and open at the region's start corner.\n const rect = this.el.getBoundingClientRect();\n const fromPointer =\n (e.clientX !== 0 || e.clientY !== 0) &&\n e.clientX >= rect.left && e.clientX <= rect.right &&\n e.clientY >= rect.top && e.clientY <= rect.bottom;\n this._contextPoint = fromPointer ? { x: e.clientX, y: e.clientY } : null;\n if (this.isOpen) this.recalculateDimensions();\n else this.open();\n };\n\n _handleDocumentContextMenu = (e: MouseEvent) => {\n const path = e.composedPath();\n // A right-click on the menu itself keeps it open and the browser's own\n // menu shut.\n if (path.includes(this.menuEl)) {\n e.preventDefault();\n return;\n }\n if (!path.includes(this.el)) this.close();\n };\n\n _handleClick = (e: MouseEvent) => {\n e.preventDefault();\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n };\n\n _handleMouseEnter = () => {\n if (this.isOpen) return;\n // A pointer passing over the trigger must not pull focus out of whatever\n // the user is typing in, so a hover-opened menu leaves focus alone.\n this._openedByHover = true;\n this.open();\n };\n\n _handleMouseLeave = (e: MouseEvent) => {\n const toEl = e.relatedTarget as HTMLElement;\n // relatedTarget is null when the pointer leaves the window entirely.\n if (!toEl) {\n this.close();\n return;\n }\n // Close hover menu if mouse did not leave to either active menu-trigger or menu-content\n const leaveToActiveMenuTrigger = toEl.closest('.menu-trigger')?.['Expressive_Menu']?.isOpen;\n if (!leaveToActiveMenuTrigger && !this.menuEl?.contains(toEl)) this.close();\n };\n\n _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath();\n const menuTarget = this._menuClickTargets.get(e);\n this._menuClickTargets.delete(e);\n // A click on the trigger belongs to the trigger's own click handler (which\n // toggles), not to outside dismissal: an Autocomplete input has no toggle,\n // so moving the caret closed its list. A context region still closes on a\n // left click, since that is how its menu is dismissed.\n if (!menuTarget && !this.options.contextMenu && path.includes(this.el)) {\n this.isTouchMoving = false;\n return;\n }\n const target = menuTarget ?? <HTMLElement>(path[0] || e.target);\n const inside = !!menuTarget || path.includes(this.menuEl) || this.menuEl?.contains(target);\n if (this._isSubmenuTriggerClick(target)) return;\n if (inside && this._closesOnClick(target)) {\n this.close();\n } else if (!inside) {\n // Do this one frame later so that if the element clicked also triggers _handleClick\n // For example, if a label for a select was clicked, that we don't close/open the menu\n this._schedule(() => this.close(), 0);\n }\n this.isTouchMoving = false;\n };\n\n // A hover-opened menu does not hold focus, so its own keydown handler never\n // sees Escape. Close it from wherever focus is, without moving focus, and\n // take the key only when it was pressed on the trigger.\n _handleDocumentKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || !this._openedByHover) return;\n if (Utils.focusIsIn(this.el)) e.preventDefault();\n this.close();\n };\n\n _handleTriggerKeydown = (e: KeyboardEvent) => {\n // A context region keeps its keys for its own content; the browser turns\n // the menu key and Shift+F10 into a contextmenu event.\n if (this.options.contextMenu) return;\n // Opening focus is delayed, so Escape must work while the trigger still owns it.\n if (e.key === 'Escape' && this.isOpen && Utils.plainKey(e) && !Utils.isComposing(e)) {\n e.preventDefault();\n this.close();\n return;\n }\n // M3: Space, Enter, Arrow Down, and Arrow Up open a closed menu.\n const opensMenu = [SPACE, 'Enter', 'ArrowDown', 'ArrowUp'].includes(e.key);\n if (!opensMenu) return;\n if (!this.isOpen) {\n e.preventDefault();\n this.open();\n } else if (this._openedByHover) {\n // The keyboard takes over a menu the pointer opened.\n e.preventDefault();\n this._openedByHover = false;\n this._focusInitialItem();\n }\n };\n\n // A scroll ends without a click, which is the only other place the flag is\n // cleared, so a new gesture has to clear it or the next tap is ignored.\n _handleMenuPointerdown = () => {\n this.isTouchMoving = false;\n };\n\n _handleDocumentTouchmove = (e: TouchEvent) => {\n const target = <HTMLElement>e.target;\n if (e.composedPath().includes(this.menuEl) || this.menuEl?.contains(target)) {\n this.isTouchMoving = true;\n }\n };\n\n _handleMenuClick = (e: MouseEvent) => {\n const target = <HTMLElement>e.target;\n // Closed shadow roots hide the original target from document listeners.\n this._menuClickTargets.set(e, target);\n const li = target.closest('li');\n if (li?.matches('.disabled, [aria-disabled=\"true\"]')) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (li && this._isSubmenuTriggerClick(target)) {\n e.preventDefault();\n e.stopPropagation();\n this._toggleSubmenu(li);\n return;\n }\n if (li) this._activateItem(li);\n };\n\n private _activateItem(li: HTMLLIElement) {\n const checked = this._toggleChecked(li);\n if (!this._notify('select', this.options.onItemClick, { args: [li], detail: { item: li } })) return;\n if (checked !== null) this._notify('change', null, { detail: { item: li, checked } });\n }\n\n // A menuitemcheckbox flips aria-checked, and a menuitemradio checks itself\n // and unchecks its group, before anyone hears of the click. Any other row,\n // or a radio that was already checked, returns null.\n private _toggleChecked(li: HTMLElement): boolean | null {\n const role = li.getAttribute('role');\n if (role === 'menuitemradio') return this._checkRadio(li);\n if (role !== 'menuitemcheckbox') return null;\n const checked = li.getAttribute('aria-checked') !== 'true';\n li.setAttribute('aria-checked', String(checked));\n return checked;\n }\n\n // A radio's group is its parent list: a <ul role=\"group\">, or for radio\n // rows outside any group, their menu.\n private _checkRadio(li: HTMLElement): true | null {\n if (li.getAttribute('aria-checked') === 'true') return null;\n li.parentElement.querySelectorAll(':scope > li[role=\"menuitemradio\"]').forEach((radio) => {\n radio.setAttribute('aria-checked', String(radio === li));\n });\n return true;\n }\n\n private _isCheckboxRow(el: Element | null | undefined) {\n return el?.closest('li')?.getAttribute('role') === 'menuitemcheckbox';\n }\n\n // isTouchMoving: a scroll on mobile is not a choice.\n private _closesOnClick(target: HTMLElement) {\n return this.options.closeOnClick && !this.isTouchMoving && !this._keepsOpen(target);\n }\n\n // Click and Space keep a checkbox menu open so several items can be\n // toggled. Space keeps a radio menu open too; a click on a radio closes it.\n private _keepsOpen(target: HTMLElement) {\n const role = target.closest('li')?.getAttribute('role');\n if (role === 'menuitemcheckbox') return true;\n return this._spaceActivation && role === 'menuitemradio';\n }\n\n // Enter toggles a checkbox item and then closes, as it does on any item.\n private _closeAfterEnter(e: KeyboardEvent, row: Element | undefined) {\n if (e.key === 'Enter' && this.options.closeOnClick && this._isCheckboxRow(row)) this.close();\n }\n\n private _setupAccessibility() {\n if (!this.menuEl) return;\n if (!this.menuEl.hasAttribute('role')) this.menuEl.setAttribute('role', 'menu');\n\n const menus = [this.menuEl, ...this.menuEl.querySelectorAll('menu')];\n menus.forEach((menu) => {\n if (!menu.hasAttribute('role')) menu.setAttribute('role', 'menu');\n if (menu.getAttribute('role') !== 'menu') return;\n\n menu.querySelectorAll(ROWS).forEach((li) => {\n if (li.classList.contains('divider')) {\n if (!li.hasAttribute('role')) li.setAttribute('role', 'separator');\n return;\n }\n if (li.classList.contains('gap')) {\n li.setAttribute('aria-hidden', 'true');\n return;\n }\n if (li.classList.contains('label') || li.classList.contains('optgroup')) {\n if (!li.hasAttribute('role')) li.setAttribute('role', 'presentation');\n return;\n }\n if (!li.hasAttribute('role')) li.setAttribute('role', 'menuitem');\n if (li.classList.contains('disabled') && !li.hasAttribute('aria-disabled')) {\n li.setAttribute('aria-disabled', 'true');\n }\n });\n });\n }\n\n private _isSubmenuTriggerClick(target: HTMLElement) {\n if (!this.menuEl) return false;\n const li = target.closest('li');\n if (!li || !this.menuEl.contains(li)) return false;\n const submenu = li.querySelector(':scope > menu');\n if (!submenu) return false;\n return !submenu.contains(target);\n }\n\n private _setupSubmenus() {\n this.menuEl?.querySelectorAll('li').forEach((li) => {\n if (!li.querySelector(':scope > menu')) return;\n const trigger = li.querySelector(':scope > a, :scope > button, :scope > span') ?? li;\n trigger.setAttribute('aria-haspopup', 'menu');\n trigger.setAttribute('aria-expanded', 'false');\n });\n }\n\n private _toggleSubmenu(li: HTMLElement) {\n const open = !li.classList.contains('open');\n li.parentElement?.querySelectorAll(':scope > li.open').forEach((other) => {\n if (other !== li) this._closeSubmenu(other as HTMLElement);\n });\n li.classList.toggle('open', open);\n if (open) this._alignSubmenu(li);\n this._syncSubmenuAria(li, open);\n }\n\n private _syncSubmenuAria(li: HTMLElement, open: boolean) {\n const trigger = li.querySelector(':scope > a, :scope > button, :scope > span') ?? li;\n trigger.setAttribute('aria-expanded', open ? 'true' : 'false');\n }\n\n private _handleSubmenuAlign = (e: MouseEvent) => {\n const target = e.target;\n if (!(target instanceof Element)) return;\n const li = target.closest('li');\n if (li?.querySelector(':scope > menu') && this.menuEl?.contains(li)) {\n this._alignSubmenu(li as HTMLElement);\n }\n };\n\n private _alignSubmenu(li: HTMLElement) {\n const menu = li.querySelector(':scope > menu') as HTMLElement | null;\n if (!menu) return;\n // Flyouts stay `display: block` (visibility/opacity hide them) so the\n // rect is readable without temporarily painting the menu.\n li.classList.remove('submenu-start');\n const rect = menu.getBoundingClientRect();\n if (rect.left < 8 || rect.right > window.innerWidth - 8) li.classList.add('submenu-start');\n }\n\n private _closeSubmenu(li: HTMLElement) {\n li.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(li, false);\n }\n\n private _closeSubmenus() {\n this.menuEl?.querySelectorAll('li.open').forEach((li) => this._closeSubmenu(li as HTMLElement));\n }\n\n private _containingSubmenu(e: Event): HTMLElement | null {\n const target = e.target;\n if (!(target instanceof Element)) return null;\n const submenu = target.closest('li > menu');\n if (submenu instanceof HTMLElement && this.menuEl?.contains(submenu)) return submenu;\n return null;\n }\n\n private _focusedRow(e: Event): HTMLElement | null {\n const target = e.target;\n if (!(target instanceof Element)) return null;\n const li = target.closest('li');\n if (li instanceof HTMLElement && this.menuEl?.contains(li)) return li;\n return null;\n }\n\n _handleMenuKeydown = (e: KeyboardEvent) => {\n if (!this.isOpen || !Utils.plainKey(e) || Utils.isComposing(e)) return;\n const list = this._containingSubmenu(e) ?? this.menuEl;\n const rtl = getComputedStyle(list).direction === 'rtl';\n const openKey = rtl ? 'ArrowLeft' : 'ArrowRight';\n const backKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n if ([openKey, backKey, 'ArrowUp', 'ArrowDown', 'Escape', 'Tab'].includes(e.key)) {\n clearTimeout(this.filterTimeout);\n this._resetFilterQuery();\n }\n if (e.key === 'Tab') {\n e.preventDefault();\n this.close();\n } else if (e.key === openKey) {\n const li = this._focusedRow(e);\n if (li?.querySelector(':scope > menu') && !li.matches('.disabled, [aria-disabled=\"true\"]')) {\n e.preventDefault();\n li.classList.add('open');\n this._alignSubmenu(li);\n this._syncSubmenuAria(li, true);\n const first = Array.from(li.querySelector(':scope > menu').children).find(\n child => child instanceof HTMLElement && child.tabIndex !== -1\n ) as HTMLElement | undefined;\n if (first) this._focusRow(first);\n }\n } else if (e.key === backKey) {\n const submenu = this._containingSubmenu(e);\n if (submenu) {\n e.preventDefault();\n const parentLi = submenu.parentElement as HTMLElement;\n this._closeSubmenu(parentLi);\n this._focusRow(parentLi);\n }\n }\n // Up and Down move a row, Home and End to the ends.\n else if (this._moveFocus(list, e)) {\n e.preventDefault();\n }\n // SPACE OR ENTER selects the focused item.\n else if (e.key === 'Enter' || e.key === SPACE) {\n const li = this._focusedRow(e);\n e.preventDefault();\n if (li?.matches('.disabled, [aria-disabled=\"true\"]')) return;\n if (li?.querySelector(':scope > menu')) {\n this._toggleSubmenu(li);\n return;\n }\n const focusedElement = li ?? this.menuEl.children[this.focusedIndex];\n const activatableElement = <HTMLElement>focusedElement?.querySelector(':scope > a, :scope > button');\n this._spaceActivation = e.key === SPACE;\n if (!!activatableElement) {\n activatableElement.click();\n } else if (focusedElement instanceof HTMLElement) {\n focusedElement.click();\n }\n this._spaceActivation = false;\n this._closeAfterEnter(e, focusedElement);\n }\n // Close menu on ESC\n else if (e.key === 'Escape') {\n e.preventDefault();\n const openSub = this._containingSubmenu(e)?.parentElement ??\n Array.from(this.menuEl.querySelectorAll('li.open')).reverse()[0];\n if (openSub) {\n this._closeSubmenu(openSub as HTMLElement);\n this._focusRow(openSub as HTMLElement);\n } else {\n this.close();\n }\n }\n\n const keyText = e.key.toLowerCase();\n if (e.key.length === 1 && e.key !== SPACE) {\n this.filterQuery.push(keyText);\n const string = this.filterQuery.join('');\n // textContent rather than innerText: this scans every item on every\n // keystroke, and innerText forces a layout flush per item.\n const newOptionEl = this._rows(list).find(\n (el) => !el.matches('.disabled, [aria-disabled=\"true\"]') &&\n Array.from(el.childNodes).filter(node => !(node instanceof Element && node.matches('menu')))\n .map(node => node.textContent).join('').trim().toLowerCase().startsWith(string)\n );\n if (newOptionEl) {\n this._focusRow(newOptionEl as HTMLElement);\n }\n // Re-arm rather than stack: without the clear, every keystroke left a live\n // timer behind and the query could reset while the user was still typing.\n clearTimeout(this.filterTimeout);\n this.filterTimeout = setTimeout(this._resetFilterQuery, 1000);\n }\n };\n\n _handleWindowResize = () => {\n // Only re-place the menu if it's still visible\n // Accounts for elements hiding via media queries\n if (this.el.offsetParent) {\n this.recalculateDimensions();\n }\n };\n\n _resetFilterQuery = () => {\n this.filterQuery = [];\n };\n\n private _restoreInert() {\n if (this.menuEl) restoreAttribute(this.menuEl, 'inert', this._originalInert);\n }\n\n // focusedIndex is reset on close and only covers one list, so clearing by\n // index left an old highlight behind after reopening or a typeahead jump.\n private _clearActive() {\n this.menuEl?.querySelectorAll('li.active').forEach((li) => li.classList.remove('active'));\n }\n\n private _focusRow(item: HTMLElement) {\n this._clearActive();\n this.focusedIndex = Array.from(item.parentElement.children).indexOf(item);\n item.focus({ preventScroll: true });\n item.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n\n _resetMenuStyles() {\n // destroy() runs this even when the menu target was never found.\n if (!this.menuEl) return;\n // A no-op unless open, so a removed menu does not throw.\n this.menuEl.hidePopover();\n this._resetMenuPositioningStyles();\n this.menuEl.style.transform = '';\n this.menuEl.style.opacity = '';\n }\n\n _resetMenuPositioningStyles() {\n this.menuEl.style.width = '';\n this.menuEl.style.height = '';\n this.menuEl.style.left = '';\n this.menuEl.style.top = '';\n this.menuEl.style.transformOrigin = '';\n for (const property of ANCHOR_STYLES) this.menuEl.style.removeProperty(property);\n this._stopReanchoring();\n }\n\n _moveMenuToElement() {\n if (this.options.container) this.options.container.append(this.menuEl);\n else this.el.after(this.menuEl);\n }\n\n _makeMenuFocusable() {\n if (!this.menuEl) return;\n // Manual: Menu keeps its own light dismiss and Escape. An auto popover\n // would close an Autocomplete list when its input is clicked, close any\n // other open popover, and leave the top layer before the exit fade where\n // `overlay` is missing (Firefox, WebKit).\n this.menuEl.popover = 'manual';\n // Focus moves directly to menu items; the surface itself is not a stop.\n this.menuEl.tabIndex = -1;\n // Only set tabindex if it hasn't been set by user\n this.menuEl.querySelectorAll(':scope li').forEach((el) => {\n if (el.matches('.divider, .gap, .label, .optgroup, [role=\"none\"]')) {\n el.setAttribute('tabindex', '-1');\n return;\n }\n if (!el.getAttribute('tabindex')) el.setAttribute('tabindex', '0');\n });\n }\n\n /**\n * Moves focus for Up, Down, Home or End among the list's focusable rows,\n * without wrapping, and says whether the key was one of those.\n */\n private _moveFocus(list: Element, e: KeyboardEvent) {\n const rows = this._rows(list);\n const from = this._focusedRow(e) ?? list.children[this.focusedIndex];\n const index = Utils._keyIndex(e.key, rows.indexOf(from as HTMLElement), rows.length, STEPS);\n if (Number.isNaN(index)) return false;\n const row = rows[index];\n if (row) {\n this._focusRow(row);\n row.classList.add('active');\n }\n return true;\n }\n\n /** The list's rows that take focus, in document order. */\n private _rows(list: Element) {\n return Array.from(list.querySelectorAll(ROWS)).filter(\n (row): row is HTMLElement => row instanceof HTMLElement && row.tabIndex !== -1\n );\n }\n\n private _focusInitialItem() {\n if (!this.menuEl || !this.options.autoFocus) return;\n const first = this._rows(this.menuEl)[0];\n if (!first) return;\n this._clearActive();\n this.focusedIndex = Array.from(first.parentElement.children).indexOf(first);\n first.focus({ preventScroll: true });\n }\n\n _focusFocusedItem() {\n if (\n this.focusedIndex >= 0 &&\n this.focusedIndex < this.menuEl.children.length &&\n this.options.autoFocus\n ) {\n (this.menuEl.children[this.focusedIndex] as HTMLElement).focus({\n preventScroll: true\n });\n this.menuEl.children[this.focusedIndex].scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest'\n });\n }\n }\n\n /**\n * Whether a measured menu opens upward: when there is no room below, or\n * when placement 'top' asks for it and there is room above.\n */\n private _opensUp(space: { top: number; bottom: number }) {\n return space.top < 0 || (this.options.placement === 'top' && space.bottom >= 0);\n }\n\n _getMenuPosition() {\n const triggerBRect = this.el.getBoundingClientRect();\n const menuBRect = this.menuEl.getBoundingClientRect();\n\n let idealHeight = menuBRect.height;\n let idealWidth = menuBRect.width;\n let idealXPos = triggerBRect.left - menuBRect.left;\n let idealYPos = triggerBRect.top - menuBRect.top;\n\n const space = room(this.el, menuBRect, this.options.coverTrigger ? 0 : triggerBRect.height);\n\n let verticalAlignment = 'top';\n let horizontalAlignment = this.options.alignment;\n idealYPos += this.options.coverTrigger ? 0 : triggerBRect.height;\n\n // Reset isScrollable\n this.isScrollable = false;\n\n if (this._opensUp(space)) {\n if (space.bottom >= 0) {\n verticalAlignment = 'bottom';\n\n if (!this.options.coverTrigger) {\n idealYPos -= triggerBRect.height;\n }\n } else {\n this.isScrollable = true;\n\n // Determine which side has most space and cutoff at correct height\n idealHeight -= 20; // Add padding when cutoff\n if (space.bottom > space.top) {\n verticalAlignment = 'bottom';\n idealHeight += space.bottom;\n idealYPos -= this.options.coverTrigger\n ? space.bottom - 20\n : space.bottom - 20 + triggerBRect.height;\n } else {\n idealHeight += space.top;\n }\n }\n }\n\n // If preferred horizontal alignment is possible\n if (space[horizontalAlignment] < 0) {\n const oppositeAlignment = horizontalAlignment === 'left' ? 'right' : 'left';\n if (space[oppositeAlignment] >= 0) {\n horizontalAlignment = oppositeAlignment;\n } else {\n // Determine which side has most space and cutoff at correct height\n if (space.right > space.left) {\n horizontalAlignment = 'right';\n idealWidth += space.right;\n idealXPos -= space.right;\n } else {\n horizontalAlignment = 'left';\n idealWidth += space.left;\n }\n }\n }\n\n if (verticalAlignment === 'bottom') {\n idealYPos =\n idealYPos - menuBRect.height + (this.options.coverTrigger ? triggerBRect.height : 0);\n }\n if (horizontalAlignment === 'right') {\n idealXPos = idealXPos - menuBRect.width + triggerBRect.width;\n }\n return {\n x: idealXPos,\n y: idealYPos,\n verticalAlignment: verticalAlignment,\n horizontalAlignment: horizontalAlignment,\n height: idealHeight,\n width: idealWidth\n };\n }\n\n private _schedule(callback: () => void, delay: number) {\n const timer = setTimeout(() => {\n this._pendingTimers.delete(timer);\n callback();\n }, delay);\n this._pendingTimers.add(timer);\n }\n\n private _clearPendingTimers() {\n for (const timer of this._pendingTimers) clearTimeout(timer);\n this._pendingTimers.clear();\n return ++this._transition;\n }\n\n _animateIn() {\n const transition = this._transition;\n // Decided now: a hover open leaves focus alone, and if the keyboard takes\n // the menu over before the animation ends it has already placed focus,\n // so the delayed call must not pull it back to the first item.\n const focusOnOpen = !this._openedByHover;\n const duration = this.options.inDuration;\n this.menuEl.style.transition = 'none';\n // from\n this.menuEl.style.opacity = '0';\n this.menuEl.style.transform = 'scale(0.85)';\n this._schedule(() => {\n this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;\n this.menuEl.style.opacity = '1';\n this.menuEl.style.transform = 'scale(1)';\n }, 1);\n this._schedule(() => {\n if (focusOnOpen) this._focusInitialItem();\n if (transition !== this._transition) return;\n this._notify('opened', this.options.onOpenEnd, { current: () => transition === this._transition });\n }, duration);\n }\n\n _animateOut() {\n const transition = this._transition;\n const duration = this.options.outDuration;\n // easeOutQuad (opacity) & easeOutQuint\n this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;\n // to\n this.menuEl.style.opacity = '0';\n this.menuEl.style.transform = 'scale(0.85)';\n this._schedule(() => {\n this._resetMenuStyles();\n this._notify('closed', this.options.onCloseEnd, { current: () => transition === this._transition });\n }, duration);\n }\n\n _placeMenu() {\n // Set width before calculating positionInfo. Both callers reset the\n // positioning styles first, so this reads the surface's natural width.\n const natural = this.menuEl.getBoundingClientRect().width;\n // A trigger narrower than the surface's own minimum is not a constraint\n // the menu can honour: the width is written and `min-width` overrides it,\n // leaving the surface at the floor with every item inside it wrapped. So\n // constrain only to a trigger wide enough to mean something, and size by\n // content otherwise. An icon button and a split button's chevron are both\n // that case - 40dp and 48dp against a 112dp floor.\n const triggerWidth = this.el.getBoundingClientRect().width;\n const idealWidth =\n this.options.constrainWidth && !this.options.contextMenu && triggerWidth >= MIN_SURFACE_WIDTH\n ? triggerWidth\n : Math.min(MAX_SURFACE_WIDTH, Math.max(MIN_SURFACE_WIDTH, natural));\n this.menuEl.style.width = idealWidth + 'px';\n\n if (this.options.contextMenu) {\n this._placeMenuAtPoint(this._contextPoint ?? this._regionCorner());\n return;\n }\n\n if (anchorSupported && !this.options.coverTrigger && !transformed(this.el)) this._anchorMenu();\n else this._placeByCoordinates();\n }\n\n /**\n * The side an anchored menu opens on: the one asked for when the whole\n * menu fits there, or else the roomier one. The anchored height is capped\n * to its side, so a menu that would only shrink never sets off the\n * flip-block fallback, and the choice is made here.\n */\n private _side(): 'top' | 'bottom' {\n const rect = this.el.getBoundingClientRect();\n const room = { top: rect.top, bottom: window.innerHeight - rect.bottom };\n const [asked, other] = this.options.placement === 'top' ? ['top', 'bottom'] as const : ['bottom', 'top'] as const;\n return room[asked] >= this.menuEl.scrollHeight || room[asked] >= room[other] ? asked : other;\n }\n\n // Below the trigger, or above it for placement 'top', starting at its left\n // edge for alignment 'left' or its right edge for 'right', with the flips\n // position-try-fallbacks offers.\n // The height is capped to the room on the chosen side, so a long menu\n // scrolls there, as in the measured path.\n private _reanchorFrame = 0;\n\n private _anchorMenu() {\n const name = `--menu-${this.menuEl.id}`;\n Utils.setAnchorName(this.el, name, true);\n const style = this.menuEl.style;\n style.position = 'fixed';\n style.inset = 'auto';\n style.maxHeight = '100%';\n style.setProperty('position-anchor', name);\n this._placeAnchored();\n }\n\n /**\n * At most once a frame while the menu is open and something outside it\n * scrolls, an anchored menu chooses its side again and a measured one\n * follows its trigger, keeping its own scroll position. A context menu\n * stays where it opened, and the menu's own scrolling moves nothing.\n */\n private _reanchor = (event: Event) => {\n if (this._reanchorFrame || this.options.contextMenu || this.menuEl.contains(event.target as Node)) return;\n this._reanchorFrame = requestAnimationFrame(() => {\n this._reanchorFrame = 0;\n if (!this.isOpen) return;\n if (this.menuEl.style.getPropertyValue('position-anchor')) return this._placeAnchored();\n // Re-measuring clears the height, which would reset the scroll position.\n const { scrollTop } = this.menuEl;\n this.recalculateDimensions();\n this.menuEl.scrollTop = scrollTop;\n });\n };\n\n private _stopReanchoring() {\n cancelAnimationFrame(this._reanchorFrame);\n this._reanchorFrame = 0;\n }\n\n /** The anchored menu's side, the edge it starts from and its growth origin. */\n private _placeAnchored() {\n const style = this.menuEl.style;\n const [side, edge] = [this._side(), this.options.alignment === 'right' ? 'left' : 'right'];\n style.setProperty('position-area', `${side} span-${edge}`);\n style.setProperty('position-try-fallbacks', 'flip-block, flip-inline, flip-block flip-inline');\n style.transformOrigin = `${edge === 'left' ? '100%' : '0'} ${side === 'top' ? '100%' : '0'}`;\n this.isScrollable = this.menuEl.scrollHeight > this.menuEl.clientHeight;\n }\n\n private _placeByCoordinates() {\n const positionInfo = this._getMenuPosition();\n this.menuEl.style.left = positionInfo.x + 'px';\n this.menuEl.style.top = positionInfo.y + 'px';\n this.menuEl.style.height = positionInfo.height + 'px';\n this.menuEl.style.width = positionInfo.width + 'px';\n this.menuEl.style.transformOrigin = `${\n positionInfo.horizontalAlignment === 'left' ? '0' : '100%'\n } ${positionInfo.verticalAlignment === 'top' ? '0' : '100%'}`;\n }\n\n /** Where a context menu opens without a pointer: the region's start corner. */\n private _regionCorner() {\n const rect = this.el.getBoundingClientRect();\n const rtl = getComputedStyle(this.el).direction === 'rtl';\n return { x: rtl ? rect.right : rect.left, y: rect.bottom };\n }\n\n /**\n * Places a context menu with its start corner on the point, flipping to\n * the other side of the point where it would not fit. The bounds are the\n * viewport; a menu taller than it gets its height and scrolls.\n *\n * The menu rests at left/top 0 of its containing block, so its rect is the\n * offset to subtract - the same trick _getMenuPosition uses. It is measured\n * without the entry animation's scale, which a second right-click can catch.\n */\n private _placeMenuAtPoint({ x, y }: { x: number; y: number }) {\n // A running transition would still report the interpolated scale, so it\n // is suspended for the read; the target transform is unchanged after.\n const { transform, transition } = this.menuEl.style;\n this.menuEl.style.transition = 'none';\n this.menuEl.style.transform = 'none';\n const menu = this.menuEl.getBoundingClientRect();\n this.menuEl.style.transform = transform;\n this.menuEl.style.transition = transition;\n\n const bounds = { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight };\n const width = menu.width;\n const height = Math.min(menu.height, bounds.bottom - bounds.top);\n this.isScrollable = height < menu.height;\n if (this.isScrollable) this.menuEl.style.height = height + 'px';\n\n const rtl = getComputedStyle(this.el).direction === 'rtl';\n const fitsRight = x + width <= bounds.right;\n const fitsLeft = x - width >= bounds.left;\n const leftward = rtl ? fitsLeft || !fitsRight : !fitsRight && fitsLeft;\n const upward = y + height > bounds.bottom && y - height >= bounds.top;\n const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));\n const left = clamp(leftward ? x - width : x, bounds.left, bounds.right - width);\n const top = clamp(upward ? y - height : y, bounds.top, bounds.bottom - height);\n this.menuEl.style.left = left - menu.left + 'px';\n this.menuEl.style.top = top - menu.top + 'px';\n this.menuEl.style.transformOrigin = `${leftward ? '100%' : '0'} ${upward ? '100%' : '0'}`;\n }\n\n private _setExpanded(expanded: boolean) {\n if (!this.options.contextMenu) this.el.ariaExpanded = String(expanded);\n }\n\n // A trigger whose target never resolved has no menu to open.\n private get _canOpen() {\n return !this.isOpen && !!this.menuEl && this.el['Expressive_Menu'] === this;\n }\n\n /**\n * Open menu.\n */\n open = () => {\n if (!this._canOpen) return;\n const transition = this._clearPendingTimers();\n this.isOpen = true;\n // onOpenStart callback\n if (!this._notify('open', this.options.onOpenStart, { current: () => transition === this._transition })) return;\n // Reset styles\n this._resetMenuStyles();\n // The top layer: no ancestor clips or contains the open menu.\n if (this.menuEl.isConnected) this.menuEl.showPopover();\n this._restoreInert();\n this._placeMenu();\n // Do this one frame later so that we don't bind an event handler that's immediately\n // called when the event bubbles up to the document and closes the menu\n this._schedule(() => this._setupTemporaryEventHandlers(), 0);\n // Queue handlers before initial focus, including zero-duration entry.\n this._animateIn();\n this._setExpanded(true);\n };\n\n /**\n * Close menu.\n */\n close = () => {\n if (!this.isOpen) return;\n const transition = this._clearPendingTimers();\n const root = this.menuEl.getRootNode() as Document | ShadowRoot;\n const focused = root.activeElement;\n this.isOpen = false;\n this._openedByHover = false;\n this.menuEl.setAttribute('inert', '');\n clearTimeout(this.filterTimeout);\n this._resetFilterQuery();\n this.focusedIndex = -1;\n this._clearActive();\n this._closeSubmenus();\n // onCloseStart callback\n if (!this._notify('close', this.options.onCloseStart, { current: () => transition === this._transition })) return;\n this._animateOut();\n this._openEvents?.abort();\n this._setExpanded(false);\n if (this.options.autoFocus && this.menuEl.contains(focused) &&\n (root.activeElement === focused || this.el.ownerDocument.activeElement === this.el.ownerDocument.body)) {\n // A context region may not take focus itself; return to what had it.\n const back = this._contextReturn;\n (back?.isConnected && back !== this.el.ownerDocument.body ? back : this.el).focus();\n }\n this._contextReturn = null;\n this._contextPoint = null;\n };\n\n /**\n * While menu is open, you can recalculate its dimensions if its contents have changed.\n */\n recalculateDimensions = () => {\n if (this.isOpen) {\n this._resetMenuPositioningStyles();\n this._placeMenu();\n }\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["room"]
7
+ }
@@ -0,0 +1,227 @@
1
+ import {
2
+ LineChart,
3
+ cellValue,
4
+ morph,
5
+ pace
6
+ } from "./chunk-ZM3XBHWV.mjs";
7
+ import {
8
+ svgNode
9
+ } from "./chunk-ZVLOUDIJ.mjs";
10
+
11
+ // src/ts/components/sankeyChart.ts
12
+ var NODE_WIDTH = 2;
13
+ var NODE_GAP = 4;
14
+ var COLORS = 6;
15
+ var span = (text2) => Object.assign(document.createElement("span"), { textContent: text2 });
16
+ var text = (row, column) => row.cells[column]?.textContent.trim() ?? "";
17
+ var sum = (flows) => flows.reduce((total, flow) => total + flow.value, 0);
18
+ function flowOf(row, index) {
19
+ const [source, target, value] = [text(row, 0), text(row, 1), Number(cellValue(row.cells[2]))];
20
+ return source && target && value > 0 ? { row: index, source, target, value } : null;
21
+ }
22
+ function reaches(flows, from, to, seen = /* @__PURE__ */ new Set()) {
23
+ if (from === to) return true;
24
+ seen.add(from);
25
+ return flows.some((flow) => flow.source === from && !seen.has(flow.target) && reaches(flows, flow.target, to, seen));
26
+ }
27
+ function flowsOf(rows) {
28
+ const flows = [];
29
+ rows.forEach((row, index) => {
30
+ const flow = flowOf(row, index);
31
+ if (flow && !reaches(flows, flow.target, flow.source)) flows.push(flow);
32
+ });
33
+ return flows;
34
+ }
35
+ function columnOf(name, flows, columns) {
36
+ if (!columns.has(name)) {
37
+ const sources = flows.filter((flow) => flow.target === name).map((flow) => columnOf(flow.source, flows, columns) + 1);
38
+ columns.set(name, Math.max(0, ...sources));
39
+ }
40
+ return columns.get(name);
41
+ }
42
+ function nodesOf(flows) {
43
+ const columns = /* @__PURE__ */ new Map();
44
+ return [...new Set(flows.flatMap((flow) => [flow.source, flow.target]))].map((name, i) => ({
45
+ name,
46
+ color: String(i % COLORS + 1),
47
+ column: columnOf(name, flows, columns),
48
+ size: Math.max(sum(flows.filter((flow) => flow.target === name)), sum(flows.filter((flow) => flow.source === name))),
49
+ x: 0,
50
+ top: 0,
51
+ height: 0
52
+ }));
53
+ }
54
+ function place(nodes) {
55
+ const count = Math.max(...nodes.map((node) => node.column)) + 1;
56
+ const columns = Array.from({ length: count }, (_, c) => nodes.filter((node) => node.column === c));
57
+ const gap = Math.min(NODE_GAP, 50 / Math.max(...columns.map((column) => column.length)));
58
+ const room = (column) => 100 - (column.length - 1) * gap;
59
+ const total = (column) => column.reduce((height, node) => height + node.size, 0);
60
+ const scale = Math.min(...columns.map((column) => room(column) / total(column)));
61
+ columns.forEach((column, c) => {
62
+ let top = (room(column) - total(column) * scale) / 2;
63
+ for (const node of column) {
64
+ Object.assign(node, { x: c / (count - 1) * (100 - NODE_WIDTH), top, height: node.size * scale });
65
+ top += node.height + gap;
66
+ }
67
+ });
68
+ return scale;
69
+ }
70
+ function linksOf(flows, nodes, scale) {
71
+ const byName = new Map(nodes.map((node) => [node.name, node]));
72
+ const [out, into] = [/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map()];
73
+ const next = (used, node, size) => {
74
+ const top = node.top + (used.get(node) ?? 0);
75
+ used.set(node, top - node.top + size);
76
+ return top;
77
+ };
78
+ return flows.map((flow) => {
79
+ const [source, target, size] = [byName.get(flow.source), byName.get(flow.target), flow.value * scale];
80
+ return { flow, source, target, from: next(out, source, size), to: next(into, target, size), size };
81
+ });
82
+ }
83
+ var SankeyChart = class extends LineChart {
84
+ get _type() {
85
+ return "sankey-chart";
86
+ }
87
+ /** The value column is the one series; the target column is read on its own. */
88
+ get _seriesFrom() {
89
+ return 2;
90
+ }
91
+ get _seriesTo() {
92
+ return 3;
93
+ }
94
+ /** The links carry the values, so there is no value axis. */
95
+ get _axis() {
96
+ return false;
97
+ }
98
+ /** The links the keys and pointer reach. */
99
+ get _count() {
100
+ return this._links?.length ?? 0;
101
+ }
102
+ /** Highlights one link, numbered in table order among those drawn. Pass -1 to hide the tooltip. */
103
+ show(index) {
104
+ if (!this._tooltip || index === this.activeIndex) return;
105
+ this.activeIndex = index;
106
+ const link = this._links[index];
107
+ this._paths.forEach((path, i) => path.classList.toggle("active", i === index));
108
+ this._tooltip.hidden = !link;
109
+ if (link) this._fill(link);
110
+ }
111
+ /**
112
+ * Fills the tooltip beside the link's middle: its source and target under
113
+ * their column headers, with their nodes' colors, and the value cell's
114
+ * text, as the author wrote them. Past the middle it opens back over the plot.
115
+ */
116
+ _fill({ flow, source, target, from, to, size }) {
117
+ const x = this._across((source.x + NODE_WIDTH + target.x) / 2);
118
+ Object.assign(this._tooltip.style, { left: `${x}%`, top: `${(from + to + size) / 2}%` });
119
+ this._tooltip.classList.toggle("end", x > 50);
120
+ const header = this._header.map((cell) => cell.textContent.trim());
121
+ const [sourceName, targetName, value] = [span(header[0]), span(header[1]), span(header[2])];
122
+ sourceName.dataset.series = source.color;
123
+ targetName.dataset.series = target.color;
124
+ value.className = "value";
125
+ this._tooltip.replaceChildren(sourceName, span(source.name), targetName, span(target.name), value, span(text(this._rows[flow.row], 2)));
126
+ }
127
+ /** The link under the pointer, or -1 off every link. By position, since a touch keeps its first target as it drags. */
128
+ _indexAt(e) {
129
+ const hits = this.el.getRootNode().elementsFromPoint(e.clientX, e.clientY);
130
+ const link = hits.find((hit) => this._paths.includes(hit));
131
+ return this._paths.indexOf(link);
132
+ }
133
+ /**
134
+ * Steps through the links in table order. The arrows keep their meaning
135
+ * in a right-to-left chart, since table order is no direction on screen.
136
+ */
137
+ _keyTarget(key) {
138
+ if (key === "Escape") return this.activeIndex < 0 ? void 0 : -1;
139
+ const last = this._links.length - 1;
140
+ const step = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[key];
141
+ if (step) return Math.min(last, Math.max(0, this.activeIndex + step));
142
+ return { Home: 0, End: last }[key];
143
+ }
144
+ /** Reads the flows and lays out their nodes and links. Without a link to draw, the chart draws nothing. */
145
+ _read() {
146
+ super._read();
147
+ const flows = flowsOf(this._rows);
148
+ if (!flows.length) {
149
+ [this.series, this._nodes, this._links] = [[], [], []];
150
+ return;
151
+ }
152
+ this._nodes = nodesOf(flows);
153
+ this._links = linksOf(flows, this._nodes, place(this._nodes));
154
+ }
155
+ /** An x position in hundredths of the plot, mirrored in a right-to-left chart. */
156
+ _across(x) {
157
+ return this._reversed ? 100 - x : x;
158
+ }
159
+ /** A node as path data: a rectangle. */
160
+ _nodePath({ x, top, height }) {
161
+ const [start, end] = [this._across(x), this._across(x + NODE_WIDTH)];
162
+ return `M${start},${top}H${end}V${top + height}H${start}Z`;
163
+ }
164
+ /** A link as path data: two curves from the source's edge to the target's, closed between them. */
165
+ _linkPath({ source, target, from, to, size }) {
166
+ const [x0, x1] = [source.x + NODE_WIDTH, target.x];
167
+ const [start, middle, end] = [this._across(x0), this._across((x0 + x1) / 2), this._across(x1)];
168
+ return `M${start},${from}C${middle},${from} ${middle},${to} ${end},${to}V${to + size}C${middle},${to + size} ${middle},${from + size} ${start},${from + size}Z`;
169
+ }
170
+ /**
171
+ * The links, then the nodes over their ends. Neither has a stroke, so the
172
+ * stretched SVG keeps their sizes. After update(), each shape still in the
173
+ * table moves from where it was: a link found by its source and target
174
+ * names, a node by its name.
175
+ */
176
+ _draw() {
177
+ const svg = svgNode("svg", {
178
+ viewBox: "0 0 100 100",
179
+ preserveAspectRatio: "none",
180
+ "aria-hidden": "true",
181
+ focusable: "false"
182
+ });
183
+ const [was, timing] = [this._shapes ?? /* @__PURE__ */ new Map(), this._before.length ? pace(this.el) : null];
184
+ this._shapes = /* @__PURE__ */ new Map();
185
+ const shape = (className, key, color, d) => {
186
+ const path = svgNode("path", { class: className, "data-series": color, d });
187
+ if (timing && was.has(key)) morph(path, was.get(key), timing);
188
+ this._shapes.set(key, d);
189
+ return path;
190
+ };
191
+ this._paths = this._links.map((link) => shape("sankey-chart-link", JSON.stringify([link.source.name, link.target.name]), link.source.color, this._linkPath(link)));
192
+ const nodes = this._nodes.map((node) => shape("sankey-chart-node", JSON.stringify(node.name), node.color, this._nodePath(node)));
193
+ svg.append(...this._paths, ...nodes);
194
+ return svg;
195
+ }
196
+ /**
197
+ * The node names, over the drawing, each level with its node and toward
198
+ * the plot's middle: after the node, or before it in the last column.
199
+ * They are placed from the inline start, so they need no mirroring.
200
+ */
201
+ _axes() {
202
+ const names = document.createElement("div");
203
+ names.className = "sankey-chart-names";
204
+ names.setAttribute("aria-hidden", "true");
205
+ const last = Math.max(...this._nodes.map((node) => node.column));
206
+ names.append(...this._nodes.map((node) => this._name(node, node.column === last)));
207
+ return [names];
208
+ }
209
+ _name({ name, x, top, height }, last) {
210
+ const span2 = document.createElement("span");
211
+ span2.className = last ? "sankey-chart-name end" : "sankey-chart-name";
212
+ span2.textContent = name;
213
+ span2.style.setProperty("--sankey-chart-x", `${last ? x : x + NODE_WIDTH}%`);
214
+ span2.style.setProperty("--sankey-chart-y", `${top + height / 2}%`);
215
+ return span2;
216
+ }
217
+ /** No row labels or legend: the nodes carry the names. */
218
+ _guides() {
219
+ return [];
220
+ }
221
+ };
222
+ SankeyChart.key = "Expressive_SankeyChart";
223
+
224
+ export {
225
+ SankeyChart
226
+ };
227
+ //# sourceMappingURL=chunk-CZSQHXEV.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/sankeyChart.ts"],
4
+ "sourcesContent": ["import { svgNode } from '../core/utils';\nimport { LineChart, LineChartOptions, cellValue, morph, pace } from './lineChart';\n\nexport type SankeyChartOptions = LineChartOptions;\n\n// ponytail: fixed shares of the plot; tokens if authors ask to tune them.\n/** A node's width, in hundredths of the plot's width. */\nconst NODE_WIDTH = 2;\n/** The gap between nodes in a column, in hundredths of the plot's height. */\nconst NODE_GAP = 4;\n// ponytail: nodes past six repeat the colors, as pie chart rows do.\nconst COLORS = 6;\n\n/** A row that draws a link: its index, its source and target names, and its value. */\ninterface Flow {\n row: number;\n source: string;\n target: string;\n value: number;\n}\n\n/** A node: its name, color, column and size in value units, and where it sits, in hundredths of the plot. */\ninterface Node {\n name: string;\n color: string;\n column: number;\n size: number;\n x: number;\n top: number;\n height: number;\n}\n\n/** A drawn link: its flow, its ends' nodes, its top at each end and its thickness, in hundredths of the plot. */\ninterface Link {\n flow: Flow;\n source: Node;\n target: Node;\n from: number;\n to: number;\n size: number;\n}\n\n/** A tooltip line part. */\nconst span = (text: string) => Object.assign(document.createElement('span'), { textContent: text });\n\n/** A cell's trimmed text, or '' without the cell. */\nconst text = (row: HTMLTableRowElement, column: number) => row.cells[column]?.textContent.trim() ?? '';\n\nconst sum = (flows: Flow[]) => flows.reduce((total, flow) => total + flow.value, 0);\n\n/** A row's flow, or null for a row without both names or a positive value. */\nfunction flowOf(row: HTMLTableRowElement, index: number): Flow | null {\n // A gap's null becomes 0, which draws nothing.\n const [source, target, value] = [text(row, 0), text(row, 1), Number(cellValue(row.cells[2]))];\n return source && target && value > 0 ? { row: index, source, target, value } : null;\n}\n\n/** Whether `from` reaches `to` along the flows, so a flow from `to` to `from` would close a cycle. */\nfunction reaches(flows: Flow[], from: string, to: string, seen = new Set<string>()): boolean {\n if (from === to) return true;\n seen.add(from);\n return flows.some((flow) => flow.source === from && !seen.has(flow.target) && reaches(flows, flow.target, to, seen));\n}\n\n/** The rows' flows in table order, leaving out rows without one and any that would close a cycle. */\nfunction flowsOf(rows: HTMLTableRowElement[]) {\n const flows: Flow[] = [];\n rows.forEach((row, index) => {\n const flow = flowOf(row, index);\n if (flow && !reaches(flows, flow.target, flow.source)) flows.push(flow);\n });\n return flows;\n}\n\n/** A node's column: 0 without incoming flows, otherwise one past the furthest of its sources. */\nfunction columnOf(name: string, flows: Flow[], columns: Map<string, number>): number {\n if (!columns.has(name)) {\n const sources = flows.filter((flow) => flow.target === name).map((flow) => columnOf(flow.source, flows, columns) + 1);\n columns.set(name, Math.max(0, ...sources));\n }\n return columns.get(name)!;\n}\n\n/**\n * The nodes in the order their names first appear, each sized by the larger\n * of its in and out totals, and colored in that order.\n */\nfunction nodesOf(flows: Flow[]): Node[] {\n const columns = new Map<string, number>();\n return [...new Set(flows.flatMap((flow) => [flow.source, flow.target]))].map((name, i) => ({\n name,\n color: String((i % COLORS) + 1),\n column: columnOf(name, flows, columns),\n size: Math.max(sum(flows.filter((flow) => flow.target === name)), sum(flows.filter((flow) => flow.source === name))),\n x: 0,\n top: 0,\n height: 0\n }));\n}\n\n/** Sets each node's place: columns spread across the plot, each centred down it, on one scale. */\nfunction place(nodes: Node[]) {\n const count = Math.max(...nodes.map((node) => node.column)) + 1;\n const columns = Array.from({ length: count }, (_, c) => nodes.filter((node) => node.column === c));\n // Gaps take at most half the height, however many nodes a column has.\n const gap = Math.min(NODE_GAP, 50 / Math.max(...columns.map((column) => column.length)));\n const room = (column: Node[]) => 100 - (column.length - 1) * gap;\n const total = (column: Node[]) => column.reduce((height, node) => height + node.size, 0);\n // The tallest column, nodes and gaps, fills the plot.\n const scale = Math.min(...columns.map((column) => room(column) / total(column)));\n columns.forEach((column, c) => {\n let top = (room(column) - total(column) * scale) / 2;\n for (const node of column) {\n Object.assign(node, { x: (c / (count - 1)) * (100 - NODE_WIDTH), top, height: node.size * scale });\n top += node.height + gap;\n }\n });\n return scale;\n}\n\n/** Each flow's link, stacked in table order down its source's outgoing edge and its target's incoming one. */\nfunction linksOf(flows: Flow[], nodes: Node[], scale: number): Link[] {\n const byName = new Map(nodes.map((node) => [node.name, node]));\n const [out, into] = [new Map<Node, number>(), new Map<Node, number>()];\n const next = (used: Map<Node, number>, node: Node, size: number) => {\n const top = node.top + (used.get(node) ?? 0);\n used.set(node, top - node.top + size);\n return top;\n };\n return flows.map((flow) => {\n const [source, target, size] = [byName.get(flow.source)!, byName.get(flow.target)!, flow.value * scale];\n return { flow, source, target, from: next(out, source, size), to: next(into, target, size), size };\n });\n}\n\n/**\n * Sankey chart. Each row of its <table> is a flow: the first cell names the\n * source node, the second the target node, and the third holds the value.\n * Nodes stand in columns, a node with no incoming flow in the first and any\n * other one column past the furthest of its sources, and stack in the order\n * their names first appear. Each link is as thick as its value, and each\n * node as tall as the larger of its in and out totals, on one scale. A row\n * without both names or a positive value, or whose link would close a\n * cycle, draws nothing.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class SankeyChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n private _nodes: Node[];\n /** The drawn links, in table order. */\n private _links: Link[];\n /** The links' paths, in the same order. */\n private _paths: SVGPathElement[];\n /** Each drawn shape's path data, by its link's source and target names or its node's name, which update() moves from. */\n private _shapes: Map<string, string>;\n\n protected get _type() {\n return 'sankey-chart';\n }\n\n /** The value column is the one series; the target column is read on its own. */\n protected get _seriesFrom() {\n return 2;\n }\n\n protected get _seriesTo() {\n return 3;\n }\n\n /** The links carry the values, so there is no value axis. */\n protected get _axis() {\n return false;\n }\n\n static key = 'Expressive_SankeyChart';\n\n /** The links the keys and pointer reach. */\n protected get _count() {\n return this._links?.length ?? 0;\n }\n\n /** Highlights one link, numbered in table order among those drawn. Pass -1 to hide the tooltip. */\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n this.activeIndex = index;\n const link = this._links[index];\n this._paths.forEach((path, i) => path.classList.toggle('active', i === index));\n this._tooltip.hidden = !link;\n if (link) this._fill(link);\n }\n\n /**\n * Fills the tooltip beside the link's middle: its source and target under\n * their column headers, with their nodes' colors, and the value cell's\n * text, as the author wrote them. Past the middle it opens back over the plot.\n */\n private _fill({ flow, source, target, from, to, size }: Link) {\n const x = this._across((source.x + NODE_WIDTH + target.x) / 2);\n Object.assign(this._tooltip.style, { left: `${x}%`, top: `${(from + to + size) / 2}%` });\n this._tooltip.classList.toggle('end', x > 50);\n const header = this._header.map((cell) => cell.textContent.trim());\n const [sourceName, targetName, value] = [span(header[0]), span(header[1]), span(header[2])];\n sourceName.dataset.series = source.color;\n targetName.dataset.series = target.color;\n value.className = 'value';\n this._tooltip.replaceChildren(sourceName, span(source.name), targetName, span(target.name), value, span(text(this._rows[flow.row], 2)));\n }\n\n /** The link under the pointer, or -1 off every link. By position, since a touch keeps its first target as it drags. */\n protected _indexAt(e: PointerEvent) {\n const hits = (this.el.getRootNode() as Document | ShadowRoot).elementsFromPoint(e.clientX, e.clientY);\n const link = hits.find((hit) => this._paths.includes(hit as SVGPathElement));\n return this._paths.indexOf(link as SVGPathElement);\n }\n\n /**\n * Steps through the links in table order. The arrows keep their meaning\n * in a right-to-left chart, since table order is no direction on screen.\n */\n protected _keyTarget(key: string): number | undefined {\n // With nothing shown, Escape is left to a dialog or sheet around the chart.\n if (key === 'Escape') return this.activeIndex < 0 ? undefined : -1;\n const last = this._links.length - 1;\n const step = ({ ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 } as Record<string, number>)[key];\n if (step) return Math.min(last, Math.max(0, this.activeIndex + step));\n return ({ Home: 0, End: last } as Record<string, number>)[key];\n }\n\n /** Reads the flows and lays out their nodes and links. Without a link to draw, the chart draws nothing. */\n protected _read() {\n super._read();\n const flows = flowsOf(this._rows);\n if (!flows.length) {\n [this.series, this._nodes, this._links] = [[], [], []];\n return;\n }\n this._nodes = nodesOf(flows);\n this._links = linksOf(flows, this._nodes, place(this._nodes));\n }\n\n /** An x position in hundredths of the plot, mirrored in a right-to-left chart. */\n private _across(x: number) {\n return this._reversed ? 100 - x : x;\n }\n\n /** A node as path data: a rectangle. */\n private _nodePath({ x, top, height }: Node) {\n const [start, end] = [this._across(x), this._across(x + NODE_WIDTH)];\n return `M${start},${top}H${end}V${top + height}H${start}Z`;\n }\n\n /** A link as path data: two curves from the source's edge to the target's, closed between them. */\n private _linkPath({ source, target, from, to, size }: Link) {\n const [x0, x1] = [source.x + NODE_WIDTH, target.x];\n const [start, middle, end] = [this._across(x0), this._across((x0 + x1) / 2), this._across(x1)];\n return `M${start},${from}C${middle},${from} ${middle},${to} ${end},${to}`\n + `V${to + size}C${middle},${to + size} ${middle},${from + size} ${start},${from + size}Z`;\n }\n\n /**\n * The links, then the nodes over their ends. Neither has a stroke, so the\n * stretched SVG keeps their sizes. After update(), each shape still in the\n * table moves from where it was: a link found by its source and target\n * names, a node by its name.\n */\n protected _draw(): Element {\n const svg = svgNode('svg', {\n viewBox: '0 0 100 100',\n preserveAspectRatio: 'none',\n 'aria-hidden': 'true',\n focusable: 'false'\n });\n const [was, timing] = [this._shapes ?? new Map<string, string>(), this._before.length ? pace(this.el) : null];\n this._shapes = new Map();\n const shape = (className: string, key: string, color: string, d: string) => {\n const path = svgNode('path', { class: className, 'data-series': color, d }) as SVGPathElement;\n if (timing && was.has(key)) morph(path, was.get(key)!, timing);\n this._shapes.set(key, d);\n return path;\n };\n this._paths = this._links.map((link) =>\n shape('sankey-chart-link', JSON.stringify([link.source.name, link.target.name]), link.source.color, this._linkPath(link)));\n const nodes = this._nodes.map((node) => shape('sankey-chart-node', JSON.stringify(node.name), node.color, this._nodePath(node)));\n svg.append(...this._paths, ...nodes);\n return svg;\n }\n\n /**\n * The node names, over the drawing, each level with its node and toward\n * the plot's middle: after the node, or before it in the last column.\n * They are placed from the inline start, so they need no mirroring.\n */\n protected _axes(): Element[] {\n const names = document.createElement('div');\n names.className = 'sankey-chart-names';\n names.setAttribute('aria-hidden', 'true');\n const last = Math.max(...this._nodes.map((node) => node.column));\n names.append(...this._nodes.map((node) => this._name(node, node.column === last)));\n return [names];\n }\n\n private _name({ name, x, top, height }: Node, last: boolean) {\n const span = document.createElement('span');\n span.className = last ? 'sankey-chart-name end' : 'sankey-chart-name';\n span.textContent = name;\n span.style.setProperty('--sankey-chart-x', `${last ? x : x + NODE_WIDTH}%`);\n span.style.setProperty('--sankey-chart-y', `${top + height / 2}%`);\n return span;\n }\n\n /** No row labels or legend: the nodes carry the names. */\n protected _guides(): Element[] {\n return [];\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;AAOA,IAAM,aAAa;AAEnB,IAAM,WAAW;AAEjB,IAAM,SAAS;AAgCf,IAAM,OAAO,CAACA,UAAiB,OAAO,OAAO,SAAS,cAAc,MAAM,GAAG,EAAE,aAAaA,MAAK,CAAC;AAGlG,IAAM,OAAO,CAAC,KAA0B,WAAmB,IAAI,MAAM,MAAM,GAAG,YAAY,KAAK,KAAK;AAEpG,IAAM,MAAM,CAAC,UAAkB,MAAM,OAAO,CAAC,OAAO,SAAS,QAAQ,KAAK,OAAO,CAAC;AAGlF,SAAS,OAAO,KAA0B,OAA4B;AAEpE,QAAM,CAAC,QAAQ,QAAQ,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,OAAO,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5F,SAAO,UAAU,UAAU,QAAQ,IAAI,EAAE,KAAK,OAAO,QAAQ,QAAQ,MAAM,IAAI;AACjF;AAGA,SAAS,QAAQ,OAAe,MAAc,IAAY,OAAO,oBAAI,IAAY,GAAY;AAC3F,MAAI,SAAS,GAAI,QAAO;AACxB,OAAK,IAAI,IAAI;AACb,SAAO,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,QAAQ,CAAC,KAAK,IAAI,KAAK,MAAM,KAAK,QAAQ,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC;AACrH;AAGA,SAAS,QAAQ,MAA6B;AAC5C,QAAM,QAAgB,CAAC;AACvB,OAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,UAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,QAAI,QAAQ,CAAC,QAAQ,OAAO,KAAK,QAAQ,KAAK,MAAM,EAAG,OAAM,KAAK,IAAI;AAAA,EACxE,CAAC;AACD,SAAO;AACT;AAGA,SAAS,SAAS,MAAc,OAAe,SAAsC;AACnF,MAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;AACtB,UAAM,UAAU,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,IAAI,EAAE,IAAI,CAAC,SAAS,SAAS,KAAK,QAAQ,OAAO,OAAO,IAAI,CAAC;AACpH,YAAQ,IAAI,MAAM,KAAK,IAAI,GAAG,GAAG,OAAO,CAAC;AAAA,EAC3C;AACA,SAAO,QAAQ,IAAI,IAAI;AACzB;AAMA,SAAS,QAAQ,OAAuB;AACtC,QAAM,UAAU,oBAAI,IAAoB;AACxC,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,OAAO;AAAA,IACzF;AAAA,IACA,OAAO,OAAQ,IAAI,SAAU,CAAC;AAAA,IAC9B,QAAQ,SAAS,MAAM,OAAO,OAAO;AAAA,IACrC,MAAM,KAAK,IAAI,IAAI,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC,GAAG,IAAI,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC,CAAC;AAAA,IACnH,GAAG;AAAA,IACH,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,EAAE;AACJ;AAGA,SAAS,MAAM,OAAe;AAC5B,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC,IAAI;AAC9D,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,MAAM,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC;AAEjG,QAAM,MAAM,KAAK,IAAI,UAAU,KAAK,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAAC;AACvF,QAAM,OAAO,CAAC,WAAmB,OAAO,OAAO,SAAS,KAAK;AAC7D,QAAM,QAAQ,CAAC,WAAmB,OAAO,OAAO,CAAC,QAAQ,SAAS,SAAS,KAAK,MAAM,CAAC;AAEvF,QAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC,WAAW,KAAK,MAAM,IAAI,MAAM,MAAM,CAAC,CAAC;AAC/E,UAAQ,QAAQ,CAAC,QAAQ,MAAM;AAC7B,QAAI,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,SAAS;AACnD,eAAW,QAAQ,QAAQ;AACzB,aAAO,OAAO,MAAM,EAAE,GAAI,KAAK,QAAQ,MAAO,MAAM,aAAa,KAAK,QAAQ,KAAK,OAAO,MAAM,CAAC;AACjG,aAAO,KAAK,SAAS;AAAA,IACvB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAGA,SAAS,QAAQ,OAAe,OAAe,OAAuB;AACpE,QAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7D,QAAM,CAAC,KAAK,IAAI,IAAI,CAAC,oBAAI,IAAkB,GAAG,oBAAI,IAAkB,CAAC;AACrE,QAAM,OAAO,CAAC,MAAyB,MAAY,SAAiB;AAClE,UAAM,MAAM,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK;AAC1C,SAAK,IAAI,MAAM,MAAM,KAAK,MAAM,IAAI;AACpC,WAAO;AAAA,EACT;AACA,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,CAAC,QAAQ,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,MAAM,GAAI,OAAO,IAAI,KAAK,MAAM,GAAI,KAAK,QAAQ,KAAK;AACtG,WAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,KAAK,KAAK,QAAQ,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,IAAI,GAAG,KAAK;AAAA,EACnG,CAAC;AACH;AAeO,IAAM,cAAN,cAA0B,UAAU;AAAA,EAUzC,IAAc,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAc,cAAc;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,IAAc,YAAY;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAc,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA;AAAA,EAKA,IAAc,SAAS;AACrB,WAAO,KAAK,QAAQ,UAAU;AAAA,EAChC;AAAA;AAAA,EAGA,KAAK,OAAe;AAClB,QAAI,CAAC,KAAK,YAAY,UAAU,KAAK,YAAa;AAClD,SAAK,cAAc;AACnB,UAAM,OAAO,KAAK,OAAO,KAAK;AAC9B,SAAK,OAAO,QAAQ,CAAC,MAAM,MAAM,KAAK,UAAU,OAAO,UAAU,MAAM,KAAK,CAAC;AAC7E,SAAK,SAAS,SAAS,CAAC;AACxB,QAAI,KAAM,MAAK,MAAM,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,MAAM,EAAE,MAAM,QAAQ,QAAQ,MAAM,IAAI,KAAK,GAAS;AAC5D,UAAM,IAAI,KAAK,SAAS,OAAO,IAAI,aAAa,OAAO,KAAK,CAAC;AAC7D,WAAO,OAAO,KAAK,SAAS,OAAO,EAAE,MAAM,GAAG,CAAC,KAAK,KAAK,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,CAAC;AACvF,SAAK,SAAS,UAAU,OAAO,OAAO,IAAI,EAAE;AAC5C,UAAM,SAAS,KAAK,QAAQ,IAAI,CAAC,SAAS,KAAK,YAAY,KAAK,CAAC;AACjE,UAAM,CAAC,YAAY,YAAY,KAAK,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC;AAC1F,eAAW,QAAQ,SAAS,OAAO;AACnC,eAAW,QAAQ,SAAS,OAAO;AACnC,UAAM,YAAY;AAClB,SAAK,SAAS,gBAAgB,YAAY,KAAK,OAAO,IAAI,GAAG,YAAY,KAAK,OAAO,IAAI,GAAG,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;AAAA,EACxI;AAAA;AAAA,EAGU,SAAS,GAAiB;AAClC,UAAM,OAAQ,KAAK,GAAG,YAAY,EAA4B,kBAAkB,EAAE,SAAS,EAAE,OAAO;AACpG,UAAM,OAAO,KAAK,KAAK,CAAC,QAAQ,KAAK,OAAO,SAAS,GAAqB,CAAC;AAC3E,WAAO,KAAK,OAAO,QAAQ,IAAsB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,WAAW,KAAiC;AAEpD,QAAI,QAAQ,SAAU,QAAO,KAAK,cAAc,IAAI,SAAY;AAChE,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,UAAM,OAAQ,EAAE,YAAY,GAAG,WAAW,GAAG,WAAW,IAAI,SAAS,GAAG,EAA6B,GAAG;AACxG,QAAI,KAAM,QAAO,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,cAAc,IAAI,CAAC;AACpE,WAAQ,EAAE,MAAM,GAAG,KAAK,KAAK,EAA6B,GAAG;AAAA,EAC/D;AAAA;AAAA,EAGU,QAAQ;AAChB,UAAM,MAAM;AACZ,UAAM,QAAQ,QAAQ,KAAK,KAAK;AAChC,QAAI,CAAC,MAAM,QAAQ;AACjB,OAAC,KAAK,QAAQ,KAAK,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACrD;AAAA,IACF;AACA,SAAK,SAAS,QAAQ,KAAK;AAC3B,SAAK,SAAS,QAAQ,OAAO,KAAK,QAAQ,MAAM,KAAK,MAAM,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGQ,QAAQ,GAAW;AACzB,WAAO,KAAK,YAAY,MAAM,IAAI;AAAA,EACpC;AAAA;AAAA,EAGQ,UAAU,EAAE,GAAG,KAAK,OAAO,GAAS;AAC1C,UAAM,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,QAAQ,CAAC,GAAG,KAAK,QAAQ,IAAI,UAAU,CAAC;AACnE,WAAO,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,MAAM,MAAM,IAAI,KAAK;AAAA,EACzD;AAAA;AAAA,EAGQ,UAAU,EAAE,QAAQ,QAAQ,MAAM,IAAI,KAAK,GAAS;AAC1D,UAAM,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,IAAI,YAAY,OAAO,CAAC;AACjD,UAAM,CAAC,OAAO,QAAQ,GAAG,IAAI,CAAC,KAAK,QAAQ,EAAE,GAAG,KAAK,SAAS,KAAK,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;AAC7F,WAAO,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAC/D,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,QAAiB;AACzB,UAAM,MAAM,QAAQ,OAAO;AAAA,MACzB,SAAS;AAAA,MACT,qBAAqB;AAAA,MACrB,eAAe;AAAA,MACf,WAAW;AAAA,IACb,CAAC;AACD,UAAM,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,WAAW,oBAAI,IAAoB,GAAG,KAAK,QAAQ,SAAS,KAAK,KAAK,EAAE,IAAI,IAAI;AAC5G,SAAK,UAAU,oBAAI,IAAI;AACvB,UAAM,QAAQ,CAAC,WAAmB,KAAa,OAAe,MAAc;AAC1E,YAAM,OAAO,QAAQ,QAAQ,EAAE,OAAO,WAAW,eAAe,OAAO,EAAE,CAAC;AAC1E,UAAI,UAAU,IAAI,IAAI,GAAG,EAAG,OAAM,MAAM,IAAI,IAAI,GAAG,GAAI,MAAM;AAC7D,WAAK,QAAQ,IAAI,KAAK,CAAC;AACvB,aAAO;AAAA,IACT;AACA,SAAK,SAAS,KAAK,OAAO,IAAI,CAAC,SAC7B,MAAM,qBAAqB,KAAK,UAAU,CAAC,KAAK,OAAO,MAAM,KAAK,OAAO,IAAI,CAAC,GAAG,KAAK,OAAO,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC;AAC3H,UAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,SAAS,MAAM,qBAAqB,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC;AAC/H,QAAI,OAAO,GAAG,KAAK,QAAQ,GAAG,KAAK;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,QAAmB;AAC3B,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,aAAa,eAAe,MAAM;AACxC,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC;AAC/D,UAAM,OAAO,GAAG,KAAK,OAAO,IAAI,CAAC,SAAS,KAAK,MAAM,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC;AACjF,WAAO,CAAC,KAAK;AAAA,EACf;AAAA,EAEQ,MAAM,EAAE,MAAM,GAAG,KAAK,OAAO,GAAS,MAAe;AAC3D,UAAMC,QAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,MAAK,YAAY,OAAO,0BAA0B;AAClD,IAAAA,MAAK,cAAc;AACnB,IAAAA,MAAK,MAAM,YAAY,oBAAoB,GAAG,OAAO,IAAI,IAAI,UAAU,GAAG;AAC1E,IAAAA,MAAK,MAAM,YAAY,oBAAoB,GAAG,MAAM,SAAS,CAAC,GAAG;AACjE,WAAOA;AAAA,EACT;AAAA;AAAA,EAGU,UAAqB;AAC7B,WAAO,CAAC;AAAA,EACV;AACF;AAxKa,YA4BJ,MAAM;",
6
+ "names": ["text", "span"]
7
+ }
@@ -0,0 +1,121 @@
1
+ import {
2
+ Utils
3
+ } from "./chunk-ZVLOUDIJ.mjs";
4
+
5
+ // src/ts/behaviors/transferList.ts
6
+ var AVAILABLE = ".transfer-available";
7
+ var CHOSEN = ".transfer-chosen";
8
+ var MOVES = /* @__PURE__ */ new Map([
9
+ ["add", { from: AVAILABLE, to: CHOSEN, all: false }],
10
+ ["add-all", { from: AVAILABLE, to: CHOSEN, all: true }],
11
+ ["remove", { from: CHOSEN, to: AVAILABLE, all: false }],
12
+ ["remove-all", { from: CHOSEN, to: AVAILABLE, all: true }]
13
+ ]);
14
+ var _TransferList = class _TransferList {
15
+ // A second Init adds nothing: addEventListener ignores a listener it has.
16
+ static Init() {
17
+ if (typeof document === "undefined") return;
18
+ document.addEventListener("click", _TransferList._onClick);
19
+ document.addEventListener("formdata", _TransferList._onFormData, { capture: true });
20
+ document.addEventListener("reset", _TransferList._onReset, { capture: true });
21
+ }
22
+ static _onClick(e) {
23
+ const button = Utils.closestInPath(e, '.transfer-list [data-transfer]:not(:disabled, [aria-disabled="true"])');
24
+ const move = MOVES.get(button?.getAttribute("data-transfer"));
25
+ if (move) _TransferList._move(button.closest(".transfer-list"), move);
26
+ }
27
+ static _move(container, move) {
28
+ const [from, to] = [move.from, move.to].map((list) => container.querySelector(`:scope > ${list}`));
29
+ const boxes = _TransferList._boxes(container, move.from).filter((box) => !box.disabled && (move.all || box.checked));
30
+ if (!to || !boxes.length) return;
31
+ _TransferList._record(container);
32
+ const moved = boxes.map((box) => box.closest("li"));
33
+ for (const [i, row] of moved.entries()) {
34
+ boxes[i].checked = false;
35
+ to.insertBefore(row, _TransferList._slot(container, row, to));
36
+ }
37
+ const rows = [...to.children].filter((row) => moved.includes(row));
38
+ _TransferList._announce(container, rows.length, to);
39
+ container.dispatchEvent(new CustomEvent("expressive:transfer", { bubbles: true, detail: { rows, from, to } }));
40
+ }
41
+ /** The row checkboxes of one of a container's lists, in order. Only a row's own label counts, so a list nested in a row keeps its boxes. */
42
+ static _boxes(container, list) {
43
+ return [...container.querySelectorAll(`:scope > ${list} > li > label > input[type="checkbox"]`)];
44
+ }
45
+ /** Keeps the rows of both lists as they stand before a container's first move. */
46
+ static _record(container) {
47
+ if (_TransferList._starts.has(container)) return;
48
+ const rows = (list) => [...container.querySelectorAll(`:scope > ${list} > li`)];
49
+ _TransferList._starts.set(container, { available: rows(AVAILABLE), chosen: rows(CHOSEN) });
50
+ }
51
+ /**
52
+ * The row a moved row goes before. In the available list that is the first
53
+ * row that came after it before the first move; elsewhere, or for a row the
54
+ * page added since, none, so it goes last.
55
+ */
56
+ static _slot(container, row, to) {
57
+ const start = _TransferList._starts.get(container);
58
+ const order = [...start.available, ...start.chosen];
59
+ const index = order.indexOf(row);
60
+ if (!to.matches(AVAILABLE) || index < 0) return null;
61
+ return [...to.children].find((other) => order.indexOf(other) > index) ?? null;
62
+ }
63
+ static _announce(container, count, to) {
64
+ let region = _TransferList._regions.get(container);
65
+ if (!region) {
66
+ region = document.createElement("div");
67
+ region.className = "visually-hidden";
68
+ region.setAttribute("aria-live", "polite");
69
+ container.after(region);
70
+ _TransferList._regions.set(container, region);
71
+ }
72
+ region.textContent = _TransferList.i18n.moved.replace("{count}", String(count)).replace("{list}", _TransferList._name(to));
73
+ }
74
+ /** A list's `aria-label`, or the text of the elements its `aria-labelledby` names. */
75
+ static _name(list) {
76
+ const label = list.getAttribute("aria-label");
77
+ if (label !== null) return label;
78
+ const root = list.getRootNode();
79
+ const ids = (list.getAttribute("aria-labelledby") ?? "").split(/\s+/);
80
+ return ids.map((id) => root.getElementById(id)?.textContent.trim()).filter(Boolean).join(" ");
81
+ }
82
+ static _onFormData(e) {
83
+ const containers = e.target.querySelectorAll('.transfer-list:not([data-name=""])[data-name]');
84
+ for (const container of containers) {
85
+ for (const box of _TransferList._boxes(container, CHOSEN).filter(_TransferList._submits)) {
86
+ e.formData.append(container.dataset.name, box.value);
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Whether a chosen row submits. A disabled fieldset leaves it out, as it
92
+ * does its own fields outside the first legend. A row's own disabled box
93
+ * only keeps the row in place, so it still submits.
94
+ */
95
+ static _submits(box) {
96
+ return !box.matches("fieldset[disabled] > :not(legend:first-of-type) *");
97
+ }
98
+ static _onReset(e) {
99
+ const containers = [...e.target.querySelectorAll(".transfer-list")];
100
+ setTimeout(() => {
101
+ if (!e.defaultPrevented) containers.forEach(_TransferList._restore);
102
+ });
103
+ }
104
+ /** Puts every row a container had before its first move back in its list and order. */
105
+ static _restore(container) {
106
+ const start = _TransferList._starts.get(container);
107
+ if (!start) return;
108
+ const kept = (rows) => rows.filter((row) => container.contains(row));
109
+ container.querySelector(`:scope > ${AVAILABLE}`)?.append(...kept(start.available));
110
+ container.querySelector(`:scope > ${CHOSEN}`)?.append(...kept(start.chosen));
111
+ }
112
+ };
113
+ _TransferList.i18n = { moved: "Moved {count} to {list}" };
114
+ _TransferList._starts = /* @__PURE__ */ new WeakMap();
115
+ _TransferList._regions = /* @__PURE__ */ new WeakMap();
116
+ var TransferList = _TransferList;
117
+
118
+ export {
119
+ TransferList
120
+ };
121
+ //# sourceMappingURL=chunk-DZYVU75J.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/behaviors/transferList.ts"],
4
+ "sourcesContent": ["import { Utils } from '../core/utils';\n\nconst AVAILABLE = '.transfer-available';\nconst CHOSEN = '.transfer-chosen';\n\n/** Each button's source list, destination list, and whether it moves every row or only the checked ones. */\nconst MOVES = new Map([\n ['add', { from: AVAILABLE, to: CHOSEN, all: false }],\n ['add-all', { from: AVAILABLE, to: CHOSEN, all: true }],\n ['remove', { from: CHOSEN, to: AVAILABLE, all: false }],\n ['remove-all', { from: CHOSEN, to: AVAILABLE, all: true }]\n]);\n\n/** The rows of both lists as they stood before a container's first move. */\ninterface Start {\n available: Element[];\n chosen: Element[];\n}\n\n/**\n * Transfer lists. A `.transfer-list` holds a `.transfer-available` and a\n * `.transfer-chosen` list of checkbox rows, with `[data-transfer]` buttons\n * between them. `add` and `remove` move the checked rows to the other list,\n * `add-all` and `remove-all` every row, skipping rows whose box is disabled.\n * Moved rows arrive unchecked. The chosen list keeps the order rows arrived\n * in; a row moved back returns to its slot in the order the lists had before\n * the first move. A form reset puts every row back there.\n *\n * After each move the container fires a bubbling `expressive:transfer` event\n * whose `detail` is `{ rows, from, to }`, and a polite live region beside it\n * announces the move. `TransferList.i18n.moved` holds that text.\n *\n * The checkboxes carry no name. When the form builds its data, each row of\n * the chosen list adds its checkbox value under the container's `data-name`,\n * in the chosen list's order. The listeners are on the document, so a list\n * added later needs no call, but a form inside a shadow root gets no entries.\n */\nexport class TransferList {\n static i18n = { moved: 'Moved {count} to {list}' };\n private static _starts = new WeakMap<Element, Start>();\n private static _regions = new WeakMap<Element, HTMLElement>();\n\n // A second Init adds nothing: addEventListener ignores a listener it has.\n static Init() {\n if (typeof document === 'undefined') return;\n document.addEventListener('click', TransferList._onClick);\n document.addEventListener('formdata', TransferList._onFormData, { capture: true });\n document.addEventListener('reset', TransferList._onReset, { capture: true });\n }\n\n private static _onClick(e: MouseEvent) {\n // A click on a disabled button's icon still reaches the document, so the selector skips it.\n const button = Utils.closestInPath(e, '.transfer-list [data-transfer]:not(:disabled, [aria-disabled=\"true\"])');\n const move = MOVES.get(button?.getAttribute('data-transfer'));\n if (move) TransferList._move(button.closest('.transfer-list'), move);\n }\n\n private static _move(container: Element, move: { from: string; to: string; all: boolean }) {\n const [from, to] = [move.from, move.to].map((list) => container.querySelector(`:scope > ${list}`));\n const boxes = TransferList._boxes(container, move.from).filter((box) => !box.disabled && (move.all || box.checked));\n if (!to || !boxes.length) return;\n TransferList._record(container);\n const moved: Element[] = boxes.map((box) => box.closest('li'));\n for (const [i, row] of moved.entries()) {\n boxes[i].checked = false;\n to.insertBefore(row, TransferList._slot(container, row, to));\n }\n const rows = [...to.children].filter((row) => moved.includes(row));\n TransferList._announce(container, rows.length, to);\n container.dispatchEvent(new CustomEvent('expressive:transfer', { bubbles: true, detail: { rows, from, to } }));\n }\n\n /** The row checkboxes of one of a container's lists, in order. Only a row's own label counts, so a list nested in a row keeps its boxes. */\n private static _boxes(container: Element, list: string) {\n return [...container.querySelectorAll<HTMLInputElement>(`:scope > ${list} > li > label > input[type=\"checkbox\"]`)];\n }\n\n /** Keeps the rows of both lists as they stand before a container's first move. */\n private static _record(container: Element) {\n if (TransferList._starts.has(container)) return;\n const rows = (list: string) => [...container.querySelectorAll(`:scope > ${list} > li`)];\n TransferList._starts.set(container, { available: rows(AVAILABLE), chosen: rows(CHOSEN) });\n }\n\n /**\n * The row a moved row goes before. In the available list that is the first\n * row that came after it before the first move; elsewhere, or for a row the\n * page added since, none, so it goes last.\n */\n private static _slot(container: Element, row: Element, to: Element) {\n const start = TransferList._starts.get(container);\n const order = [...start.available, ...start.chosen];\n const index = order.indexOf(row);\n if (!to.matches(AVAILABLE) || index < 0) return null;\n return [...to.children].find((other) => order.indexOf(other) > index) ?? null;\n }\n\n private static _announce(container: Element, count: number, to: Element) {\n let region = TransferList._regions.get(container);\n if (!region) {\n region = document.createElement('div');\n region.className = 'visually-hidden';\n region.setAttribute('aria-live', 'polite');\n container.after(region);\n TransferList._regions.set(container, region);\n }\n region.textContent = TransferList.i18n.moved.replace('{count}', String(count)).replace('{list}', TransferList._name(to));\n }\n\n /** A list's `aria-label`, or the text of the elements its `aria-labelledby` names. */\n private static _name(list: Element) {\n const label = list.getAttribute('aria-label');\n if (label !== null) return label;\n const root = list.getRootNode() as Document | ShadowRoot;\n const ids = (list.getAttribute('aria-labelledby') ?? '').split(/\\s+/);\n return ids.map((id) => root.getElementById(id)?.textContent.trim()).filter(Boolean).join(' ');\n }\n\n private static _onFormData(e: FormDataEvent) {\n const containers = (e.target as HTMLFormElement).querySelectorAll<HTMLElement>('.transfer-list:not([data-name=\"\"])[data-name]');\n for (const container of containers) {\n for (const box of TransferList._boxes(container, CHOSEN).filter(TransferList._submits)) {\n e.formData.append(container.dataset.name, box.value);\n }\n }\n }\n\n /**\n * Whether a chosen row submits. A disabled fieldset leaves it out, as it\n * does its own fields outside the first legend. A row's own disabled box\n * only keeps the row in place, so it still submits.\n */\n private static _submits(box: HTMLInputElement) {\n return !box.matches('fieldset[disabled] > :not(legend:first-of-type) *');\n }\n\n private static _onReset(e: Event) {\n const containers = [...(e.target as HTMLFormElement).querySelectorAll('.transfer-list')];\n // The form resets its fields after the event, and the page may cancel it,\n // so the rows go back a task later.\n setTimeout(() => {\n if (!e.defaultPrevented) containers.forEach(TransferList._restore);\n });\n }\n\n /** Puts every row a container had before its first move back in its list and order. */\n private static _restore(container: Element) {\n const start = TransferList._starts.get(container);\n if (!start) return;\n const kept = (rows: Element[]) => rows.filter((row) => container.contains(row));\n container.querySelector(`:scope > ${AVAILABLE}`)?.append(...kept(start.available));\n container.querySelector(`:scope > ${CHOSEN}`)?.append(...kept(start.chosen));\n }\n}\n"],
5
+ "mappings": ";;;;;AAEA,IAAM,YAAY;AAClB,IAAM,SAAS;AAGf,IAAM,QAAQ,oBAAI,IAAI;AAAA,EACpB,CAAC,OAAO,EAAE,MAAM,WAAW,IAAI,QAAQ,KAAK,MAAM,CAAC;AAAA,EACnD,CAAC,WAAW,EAAE,MAAM,WAAW,IAAI,QAAQ,KAAK,KAAK,CAAC;AAAA,EACtD,CAAC,UAAU,EAAE,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,CAAC;AAAA,EACtD,CAAC,cAAc,EAAE,MAAM,QAAQ,IAAI,WAAW,KAAK,KAAK,CAAC;AAC3D,CAAC;AA0BM,IAAM,gBAAN,MAAM,cAAa;AAAA;AAAA,EAMxB,OAAO,OAAO;AACZ,QAAI,OAAO,aAAa,YAAa;AACrC,aAAS,iBAAiB,SAAS,cAAa,QAAQ;AACxD,aAAS,iBAAiB,YAAY,cAAa,aAAa,EAAE,SAAS,KAAK,CAAC;AACjF,aAAS,iBAAiB,SAAS,cAAa,UAAU,EAAE,SAAS,KAAK,CAAC;AAAA,EAC7E;AAAA,EAEA,OAAe,SAAS,GAAe;AAErC,UAAM,SAAS,MAAM,cAAc,GAAG,uEAAuE;AAC7G,UAAM,OAAO,MAAM,IAAI,QAAQ,aAAa,eAAe,CAAC;AAC5D,QAAI,KAAM,eAAa,MAAM,OAAO,QAAQ,gBAAgB,GAAG,IAAI;AAAA,EACrE;AAAA,EAEA,OAAe,MAAM,WAAoB,MAAkD;AACzF,UAAM,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,MAAM,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,UAAU,cAAc,YAAY,IAAI,EAAE,CAAC;AACjG,UAAM,QAAQ,cAAa,OAAO,WAAW,KAAK,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,aAAa,KAAK,OAAO,IAAI,QAAQ;AAClH,QAAI,CAAC,MAAM,CAAC,MAAM,OAAQ;AAC1B,kBAAa,QAAQ,SAAS;AAC9B,UAAM,QAAmB,MAAM,IAAI,CAAC,QAAQ,IAAI,QAAQ,IAAI,CAAC;AAC7D,eAAW,CAAC,GAAG,GAAG,KAAK,MAAM,QAAQ,GAAG;AACtC,YAAM,CAAC,EAAE,UAAU;AACnB,SAAG,aAAa,KAAK,cAAa,MAAM,WAAW,KAAK,EAAE,CAAC;AAAA,IAC7D;AACA,UAAM,OAAO,CAAC,GAAG,GAAG,QAAQ,EAAE,OAAO,CAAC,QAAQ,MAAM,SAAS,GAAG,CAAC;AACjE,kBAAa,UAAU,WAAW,KAAK,QAAQ,EAAE;AACjD,cAAU,cAAc,IAAI,YAAY,uBAAuB,EAAE,SAAS,MAAM,QAAQ,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,EAC/G;AAAA;AAAA,EAGA,OAAe,OAAO,WAAoB,MAAc;AACtD,WAAO,CAAC,GAAG,UAAU,iBAAmC,YAAY,IAAI,wCAAwC,CAAC;AAAA,EACnH;AAAA;AAAA,EAGA,OAAe,QAAQ,WAAoB;AACzC,QAAI,cAAa,QAAQ,IAAI,SAAS,EAAG;AACzC,UAAM,OAAO,CAAC,SAAiB,CAAC,GAAG,UAAU,iBAAiB,YAAY,IAAI,OAAO,CAAC;AACtF,kBAAa,QAAQ,IAAI,WAAW,EAAE,WAAW,KAAK,SAAS,GAAG,QAAQ,KAAK,MAAM,EAAE,CAAC;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAe,MAAM,WAAoB,KAAc,IAAa;AAClE,UAAM,QAAQ,cAAa,QAAQ,IAAI,SAAS;AAChD,UAAM,QAAQ,CAAC,GAAG,MAAM,WAAW,GAAG,MAAM,MAAM;AAClD,UAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,QAAI,CAAC,GAAG,QAAQ,SAAS,KAAK,QAAQ,EAAG,QAAO;AAChD,WAAO,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAK,CAAC,UAAU,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK;AAAA,EAC3E;AAAA,EAEA,OAAe,UAAU,WAAoB,OAAe,IAAa;AACvE,QAAI,SAAS,cAAa,SAAS,IAAI,SAAS;AAChD,QAAI,CAAC,QAAQ;AACX,eAAS,SAAS,cAAc,KAAK;AACrC,aAAO,YAAY;AACnB,aAAO,aAAa,aAAa,QAAQ;AACzC,gBAAU,MAAM,MAAM;AACtB,oBAAa,SAAS,IAAI,WAAW,MAAM;AAAA,IAC7C;AACA,WAAO,cAAc,cAAa,KAAK,MAAM,QAAQ,WAAW,OAAO,KAAK,CAAC,EAAE,QAAQ,UAAU,cAAa,MAAM,EAAE,CAAC;AAAA,EACzH;AAAA;AAAA,EAGA,OAAe,MAAM,MAAe;AAClC,UAAM,QAAQ,KAAK,aAAa,YAAY;AAC5C,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,OAAO,KAAK,aAAa,iBAAiB,KAAK,IAAI,MAAM,KAAK;AACpE,WAAO,IAAI,IAAI,CAAC,OAAO,KAAK,eAAe,EAAE,GAAG,YAAY,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC9F;AAAA,EAEA,OAAe,YAAY,GAAkB;AAC3C,UAAM,aAAc,EAAE,OAA2B,iBAA8B,+CAA+C;AAC9H,eAAW,aAAa,YAAY;AAClC,iBAAW,OAAO,cAAa,OAAO,WAAW,MAAM,EAAE,OAAO,cAAa,QAAQ,GAAG;AACtF,UAAE,SAAS,OAAO,UAAU,QAAQ,MAAM,IAAI,KAAK;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAe,SAAS,KAAuB;AAC7C,WAAO,CAAC,IAAI,QAAQ,mDAAmD;AAAA,EACzE;AAAA,EAEA,OAAe,SAAS,GAAU;AAChC,UAAM,aAAa,CAAC,GAAI,EAAE,OAA2B,iBAAiB,gBAAgB,CAAC;AAGvF,eAAW,MAAM;AACf,UAAI,CAAC,EAAE,iBAAkB,YAAW,QAAQ,cAAa,QAAQ;AAAA,IACnE,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,OAAe,SAAS,WAAoB;AAC1C,UAAM,QAAQ,cAAa,QAAQ,IAAI,SAAS;AAChD,QAAI,CAAC,MAAO;AACZ,UAAM,OAAO,CAAC,SAAoB,KAAK,OAAO,CAAC,QAAQ,UAAU,SAAS,GAAG,CAAC;AAC9E,cAAU,cAAc,YAAY,SAAS,EAAE,GAAG,OAAO,GAAG,KAAK,MAAM,SAAS,CAAC;AACjF,cAAU,cAAc,YAAY,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,MAAM,MAAM,CAAC;AAAA,EAC7E;AACF;AApHa,cACJ,OAAO,EAAE,OAAO,0BAA0B;AADtC,cAEI,UAAU,oBAAI,QAAwB;AAF1C,cAGI,WAAW,oBAAI,QAA8B;AAHvD,IAAM,eAAN;",
6
+ "names": []
7
+ }