@expressivecss/expressive 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (609) hide show
  1. package/CHANGELOG.md +1807 -1
  2. package/README.md +9 -8
  3. package/dist/css/expressive.css +19176 -11958
  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-26VUH75M.mjs +102 -0
  64. package/dist/js/chunks/chunk-26VUH75M.mjs.map +7 -0
  65. package/dist/js/chunks/chunk-2LFCOGC3.mjs +233 -0
  66. package/dist/js/chunks/chunk-2LFCOGC3.mjs.map +7 -0
  67. package/dist/js/chunks/{chunk-DXGRXYYL.mjs → chunk-36GELQGX.mjs} +29 -46
  68. package/dist/js/chunks/chunk-36GELQGX.mjs.map +7 -0
  69. package/dist/js/chunks/{chunk-74MXKKLN.mjs → chunk-3FKWIRHW.mjs} +15 -29
  70. package/dist/js/chunks/chunk-3FKWIRHW.mjs.map +7 -0
  71. package/dist/js/chunks/chunk-3KF65KGL.mjs +209 -0
  72. package/dist/js/chunks/chunk-3KF65KGL.mjs.map +7 -0
  73. package/dist/js/chunks/{chunk-KVJAVDBC.mjs → chunk-3KLZRQZI.mjs} +88 -116
  74. package/dist/js/chunks/chunk-3KLZRQZI.mjs.map +7 -0
  75. package/dist/js/chunks/{chunk-CK2XCICY.mjs → chunk-3XORNED5.mjs} +3 -11
  76. package/dist/js/chunks/chunk-3XORNED5.mjs.map +7 -0
  77. package/dist/js/chunks/chunk-4WBGAQN3.mjs +113 -0
  78. package/dist/js/chunks/chunk-4WBGAQN3.mjs.map +7 -0
  79. package/dist/js/chunks/{chunk-FM5CZOUB.mjs → chunk-5F4URJHL.mjs} +19 -30
  80. package/dist/js/chunks/chunk-5F4URJHL.mjs.map +7 -0
  81. package/dist/js/chunks/chunk-67UNY7RH.mjs +299 -0
  82. package/dist/js/chunks/chunk-67UNY7RH.mjs.map +7 -0
  83. package/dist/js/chunks/chunk-7CXNATJS.mjs +97 -0
  84. package/dist/js/chunks/chunk-7CXNATJS.mjs.map +7 -0
  85. package/dist/js/chunks/{chunk-UETTGDLI.mjs → chunk-7X44MKEQ.mjs} +43 -48
  86. package/dist/js/chunks/chunk-7X44MKEQ.mjs.map +7 -0
  87. package/dist/js/chunks/chunk-7ZAMOMGY.mjs +440 -0
  88. package/dist/js/chunks/chunk-7ZAMOMGY.mjs.map +7 -0
  89. package/dist/js/chunks/chunk-AEG6LOAJ.mjs +54 -0
  90. package/dist/js/chunks/chunk-AEG6LOAJ.mjs.map +7 -0
  91. package/dist/js/chunks/chunk-AQNFCJJ5.mjs +135 -0
  92. package/dist/js/chunks/chunk-AQNFCJJ5.mjs.map +7 -0
  93. package/dist/js/chunks/chunk-B55LWKBM.mjs +75 -0
  94. package/dist/js/chunks/chunk-B55LWKBM.mjs.map +7 -0
  95. package/dist/js/chunks/chunk-BB5VXYXT.mjs +28 -0
  96. package/dist/js/chunks/chunk-BB5VXYXT.mjs.map +7 -0
  97. package/dist/js/chunks/chunk-BDATLH3H.mjs +108 -0
  98. package/dist/js/chunks/chunk-BDATLH3H.mjs.map +7 -0
  99. package/dist/js/chunks/chunk-CWMQOT4O.mjs +232 -0
  100. package/dist/js/chunks/chunk-CWMQOT4O.mjs.map +7 -0
  101. package/dist/js/chunks/chunk-CY2CTOVM.mjs +81 -0
  102. package/dist/js/chunks/chunk-CY2CTOVM.mjs.map +7 -0
  103. package/dist/js/chunks/{chunk-NUHMOAOY.mjs → chunk-DWA5UYLJ.mjs} +363 -218
  104. package/dist/js/chunks/chunk-DWA5UYLJ.mjs.map +7 -0
  105. package/dist/js/chunks/chunk-EB2V4OKL.mjs +79 -0
  106. package/dist/js/chunks/chunk-EB2V4OKL.mjs.map +7 -0
  107. package/dist/js/chunks/chunk-EWO662ZC.mjs +188 -0
  108. package/dist/js/chunks/chunk-EWO662ZC.mjs.map +7 -0
  109. package/dist/js/chunks/{chunk-ZX6M7SWO.mjs → chunk-F7LAKFMX.mjs} +320 -141
  110. package/dist/js/chunks/chunk-F7LAKFMX.mjs.map +7 -0
  111. package/dist/js/chunks/{chunk-L27Q6ZMI.mjs → chunk-FNIIH2LU.mjs} +20 -33
  112. package/dist/js/chunks/chunk-FNIIH2LU.mjs.map +7 -0
  113. package/dist/js/chunks/chunk-GE3YMFS6.mjs +15 -0
  114. package/dist/js/chunks/chunk-GE3YMFS6.mjs.map +7 -0
  115. package/dist/js/chunks/chunk-GFWYMWYN.mjs +125 -0
  116. package/dist/js/chunks/chunk-GFWYMWYN.mjs.map +7 -0
  117. package/dist/js/chunks/chunk-GNRSYMVH.mjs +1 -0
  118. package/dist/js/chunks/chunk-H5ISU45X.mjs +87 -0
  119. package/dist/js/chunks/chunk-H5ISU45X.mjs.map +7 -0
  120. package/dist/js/chunks/{chunk-GJL6GCIU.mjs → chunk-H6YIKFAQ.mjs} +311 -186
  121. package/dist/js/chunks/chunk-H6YIKFAQ.mjs.map +7 -0
  122. package/dist/js/chunks/{chunk-BGZLF6JZ.mjs → chunk-HEH7E3KO.mjs} +155 -35
  123. package/dist/js/chunks/chunk-HEH7E3KO.mjs.map +7 -0
  124. package/dist/js/chunks/chunk-HQRLBTNM.mjs +152 -0
  125. package/dist/js/chunks/chunk-HQRLBTNM.mjs.map +7 -0
  126. package/dist/js/chunks/chunk-I2F7MLUU.mjs +137 -0
  127. package/dist/js/chunks/chunk-I2F7MLUU.mjs.map +7 -0
  128. package/dist/js/chunks/chunk-IQOTGGHX.mjs +797 -0
  129. package/dist/js/chunks/chunk-IQOTGGHX.mjs.map +7 -0
  130. package/dist/js/chunks/chunk-JH3YWKA6.mjs +225 -0
  131. package/dist/js/chunks/chunk-JH3YWKA6.mjs.map +7 -0
  132. package/dist/js/chunks/chunk-JOLJAYIJ.mjs +7 -0
  133. package/dist/js/chunks/chunk-JOLJAYIJ.mjs.map +7 -0
  134. package/dist/js/chunks/{chunk-VGNYF6FB.mjs → chunk-KOTGMCMI.mjs} +116 -24
  135. package/dist/js/chunks/chunk-KOTGMCMI.mjs.map +7 -0
  136. package/dist/js/chunks/{chunk-LQWUDNHZ.mjs → chunk-LC4O5LFS.mjs} +21 -45
  137. package/dist/js/chunks/chunk-LC4O5LFS.mjs.map +7 -0
  138. package/dist/js/chunks/chunk-LEF33SCP.mjs +127 -0
  139. package/dist/js/chunks/chunk-LEF33SCP.mjs.map +7 -0
  140. package/dist/js/chunks/{chunk-PDG64UHF.mjs → chunk-LFORZRPH.mjs} +21 -23
  141. package/dist/js/chunks/chunk-LFORZRPH.mjs.map +7 -0
  142. package/dist/js/chunks/chunk-LWLNV5EC.mjs +451 -0
  143. package/dist/js/chunks/chunk-LWLNV5EC.mjs.map +7 -0
  144. package/dist/js/chunks/chunk-LXRHUQAX.mjs +491 -0
  145. package/dist/js/chunks/chunk-LXRHUQAX.mjs.map +7 -0
  146. package/dist/js/chunks/{chunk-SFI2U4YW.mjs → chunk-MA2SZZFB.mjs} +82 -111
  147. package/dist/js/chunks/chunk-MA2SZZFB.mjs.map +7 -0
  148. package/dist/js/chunks/chunk-MDBZAMIV.mjs +121 -0
  149. package/dist/js/chunks/chunk-MDBZAMIV.mjs.map +7 -0
  150. package/dist/js/chunks/chunk-NODZ5VAD.mjs +75 -0
  151. package/dist/js/chunks/chunk-NODZ5VAD.mjs.map +7 -0
  152. package/dist/js/chunks/chunk-O2WJB6TH.mjs +365 -0
  153. package/dist/js/chunks/chunk-O2WJB6TH.mjs.map +7 -0
  154. package/dist/js/chunks/chunk-PCABY5BN.mjs +35 -0
  155. package/dist/js/chunks/chunk-PCABY5BN.mjs.map +7 -0
  156. package/dist/js/chunks/chunk-PWKYVMND.mjs +120 -0
  157. package/dist/js/chunks/chunk-PWKYVMND.mjs.map +7 -0
  158. package/dist/js/chunks/{chunk-SMY7GJSS.mjs → chunk-QHZZT7YO.mjs} +66 -38
  159. package/dist/js/chunks/chunk-QHZZT7YO.mjs.map +7 -0
  160. package/dist/js/chunks/chunk-QND56EW2.mjs +439 -0
  161. package/dist/js/chunks/chunk-QND56EW2.mjs.map +7 -0
  162. package/dist/js/chunks/chunk-QNODAANY.mjs +376 -0
  163. package/dist/js/chunks/chunk-QNODAANY.mjs.map +7 -0
  164. package/dist/js/chunks/{chunk-KHXZ2A4K.mjs → chunk-QRO5FV3I.mjs} +156 -73
  165. package/dist/js/chunks/chunk-QRO5FV3I.mjs.map +7 -0
  166. package/dist/js/chunks/chunk-R7A7JRC5.mjs +440 -0
  167. package/dist/js/chunks/chunk-R7A7JRC5.mjs.map +7 -0
  168. package/dist/js/chunks/chunk-RKG2CBFE.mjs +74 -0
  169. package/dist/js/chunks/chunk-RKG2CBFE.mjs.map +7 -0
  170. package/dist/js/chunks/{chunk-XAEAEHIX.mjs → chunk-RSNS5OYS.mjs} +38 -25
  171. package/dist/js/chunks/chunk-RSNS5OYS.mjs.map +7 -0
  172. package/dist/js/chunks/{chunk-X4ISMKE2.mjs → chunk-RUDYMEJ3.mjs} +7 -6
  173. package/dist/js/chunks/chunk-RUDYMEJ3.mjs.map +7 -0
  174. package/dist/js/chunks/chunk-STJR62SU.mjs +161 -0
  175. package/dist/js/chunks/chunk-STJR62SU.mjs.map +7 -0
  176. package/dist/js/chunks/chunk-SUSD4UTN.mjs +220 -0
  177. package/dist/js/chunks/chunk-SUSD4UTN.mjs.map +7 -0
  178. package/dist/js/chunks/{chunk-5CEAOLUA.mjs → chunk-SYBOA5HC.mjs} +26 -48
  179. package/dist/js/chunks/chunk-SYBOA5HC.mjs.map +7 -0
  180. package/dist/js/chunks/chunk-T4MOBP3J.mjs +108 -0
  181. package/dist/js/chunks/chunk-T4MOBP3J.mjs.map +7 -0
  182. package/dist/js/chunks/chunk-TM7HPGTV.mjs +342 -0
  183. package/dist/js/chunks/chunk-TM7HPGTV.mjs.map +7 -0
  184. package/dist/js/chunks/{chunk-C6CHEWYP.mjs → chunk-TMQDZSDC.mjs} +71 -35
  185. package/dist/js/chunks/chunk-TMQDZSDC.mjs.map +7 -0
  186. package/dist/js/chunks/chunk-TVSX5YA2.mjs +48 -0
  187. package/dist/js/chunks/chunk-TVSX5YA2.mjs.map +7 -0
  188. package/dist/js/chunks/chunk-UHO5CV6K.mjs +80 -0
  189. package/dist/js/chunks/chunk-UHO5CV6K.mjs.map +7 -0
  190. package/dist/js/chunks/chunk-UKCNELUN.mjs +223 -0
  191. package/dist/js/chunks/chunk-UKCNELUN.mjs.map +7 -0
  192. package/dist/js/chunks/chunk-UKQK5GWR.mjs +167 -0
  193. package/dist/js/chunks/chunk-UKQK5GWR.mjs.map +7 -0
  194. package/dist/js/chunks/{chunk-TSZYSW7F.mjs → chunk-UTSLYQ65.mjs} +21 -48
  195. package/dist/js/chunks/chunk-UTSLYQ65.mjs.map +7 -0
  196. package/dist/js/chunks/chunk-VS5OJBOD.mjs +108 -0
  197. package/dist/js/chunks/chunk-VS5OJBOD.mjs.map +7 -0
  198. package/dist/js/chunks/chunk-VZMROW5A.mjs +759 -0
  199. package/dist/js/chunks/chunk-VZMROW5A.mjs.map +7 -0
  200. package/dist/js/chunks/chunk-W6FAL3TI.mjs +38 -0
  201. package/dist/js/chunks/chunk-W6FAL3TI.mjs.map +7 -0
  202. package/dist/js/chunks/chunk-XB6Y7P5W.mjs +69 -0
  203. package/dist/js/chunks/chunk-XB6Y7P5W.mjs.map +7 -0
  204. package/dist/js/chunks/chunk-XDAMOMVD.mjs +226 -0
  205. package/dist/js/chunks/chunk-XDAMOMVD.mjs.map +7 -0
  206. package/dist/js/chunks/{chunk-WDK4T63U.mjs → chunk-XJPMW5SP.mjs} +247 -172
  207. package/dist/js/chunks/chunk-XJPMW5SP.mjs.map +7 -0
  208. package/dist/js/chunks/{chunk-KUFHW3DS.mjs → chunk-YKANQILZ.mjs} +16 -21
  209. package/dist/js/chunks/chunk-YKANQILZ.mjs.map +7 -0
  210. package/dist/js/chunks/chunk-YLZOJLDI.mjs +175 -0
  211. package/dist/js/chunks/chunk-YLZOJLDI.mjs.map +7 -0
  212. package/dist/js/chunks/chunk-ZK7YY322.mjs +514 -0
  213. package/dist/js/chunks/chunk-ZK7YY322.mjs.map +7 -0
  214. package/dist/js/expressive.cjs +10266 -3628
  215. package/dist/js/expressive.cjs.map +4 -4
  216. package/dist/js/expressive.js +10266 -3628
  217. package/dist/js/expressive.js.map +4 -4
  218. package/dist/js/expressive.min.js +23 -22
  219. package/dist/js/expressive.min.js.map +4 -4
  220. package/dist/js/expressive.mjs +181 -69
  221. package/dist/js/expressive.mjs.map +2 -2
  222. package/dist/js/internal/behaviors/bottomSheets.mjs +4 -3
  223. package/dist/js/internal/behaviors/copy.mjs +9 -0
  224. package/dist/js/internal/behaviors/copy.mjs.map +7 -0
  225. package/dist/js/internal/behaviors/dataTables.mjs +8 -0
  226. package/dist/js/internal/behaviors/dataTables.mjs.map +7 -0
  227. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  228. package/dist/js/internal/behaviors/forms.mjs +2 -2
  229. package/dist/js/internal/behaviors/imageCompare.mjs +8 -0
  230. package/dist/js/internal/behaviors/imageCompare.mjs.map +7 -0
  231. package/dist/js/internal/behaviors/lists.mjs +8 -0
  232. package/dist/js/internal/behaviors/lists.mjs.map +7 -0
  233. package/dist/js/internal/behaviors/paneResize.mjs +8 -0
  234. package/dist/js/internal/behaviors/paneResize.mjs.map +7 -0
  235. package/dist/js/internal/behaviors/sheetDrag.mjs +7 -2
  236. package/dist/js/internal/behaviors/sideSheets.mjs +4 -3
  237. package/dist/js/internal/behaviors/sortable.mjs +8 -0
  238. package/dist/js/internal/behaviors/sortable.mjs.map +7 -0
  239. package/dist/js/internal/behaviors/theme.mjs +8 -0
  240. package/dist/js/internal/behaviors/theme.mjs.map +7 -0
  241. package/dist/js/internal/behaviors/tour.mjs +8 -0
  242. package/dist/js/internal/behaviors/tour.mjs.map +7 -0
  243. package/dist/js/internal/behaviors/transferList.mjs +8 -0
  244. package/dist/js/internal/behaviors/transferList.mjs.map +7 -0
  245. package/dist/js/internal/components/appBar.mjs +3 -2
  246. package/dist/js/internal/components/autocomplete.mjs +5 -4
  247. package/dist/js/internal/components/backToTop.mjs +9 -0
  248. package/dist/js/internal/components/backToTop.mjs.map +7 -0
  249. package/dist/js/internal/components/barChart.mjs +5 -4
  250. package/dist/js/internal/components/buttonGroup.mjs +3 -2
  251. package/dist/js/internal/components/buttons.mjs +3 -3
  252. package/dist/js/internal/components/cards.mjs +3 -3
  253. package/dist/js/internal/components/carousel.mjs +3 -3
  254. package/dist/js/internal/components/cascader.mjs +10 -0
  255. package/dist/js/internal/components/cascader.mjs.map +7 -0
  256. package/dist/js/internal/components/characterCounter.mjs +3 -2
  257. package/dist/js/internal/components/chips.mjs +7 -5
  258. package/dist/js/internal/components/colorPicker.mjs +9 -0
  259. package/dist/js/internal/components/colorPicker.mjs.map +7 -0
  260. package/dist/js/internal/components/columnChart.mjs +4 -3
  261. package/dist/js/internal/components/commandPalette.mjs +3 -3
  262. package/dist/js/internal/components/confetti.mjs +3 -2
  263. package/dist/js/internal/components/currencyInput.mjs +9 -0
  264. package/dist/js/internal/components/currencyInput.mjs.map +7 -0
  265. package/dist/js/internal/components/datepicker.mjs +12 -8
  266. package/dist/js/internal/components/expandingCard.mjs +3 -3
  267. package/dist/js/internal/components/funnelChart.mjs +10 -0
  268. package/dist/js/internal/components/funnelChart.mjs.map +7 -0
  269. package/dist/js/internal/components/heatmapChart.mjs +4 -3
  270. package/dist/js/internal/components/hoverCard.mjs +9 -0
  271. package/dist/js/internal/components/hoverCard.mjs.map +7 -0
  272. package/dist/js/internal/components/index.mjs +131 -65
  273. package/dist/js/internal/components/inputMask.mjs +9 -0
  274. package/dist/js/internal/components/inputMask.mjs.map +7 -0
  275. package/dist/js/internal/components/keypad.mjs +3 -3
  276. package/dist/js/internal/components/lightbox.mjs +3 -3
  277. package/dist/js/internal/components/lineChart.mjs +41 -4
  278. package/dist/js/internal/components/loadingOverlay.mjs +9 -0
  279. package/dist/js/internal/components/loadingOverlay.mjs.map +7 -0
  280. package/dist/js/internal/components/mapView.mjs +3 -3
  281. package/dist/js/internal/components/menu.mjs +3 -3
  282. package/dist/js/internal/components/menubar.mjs +10 -0
  283. package/dist/js/internal/components/menubar.mjs.map +7 -0
  284. package/dist/js/internal/components/messageScroller.mjs +3 -3
  285. package/dist/js/internal/components/mixedChart.mjs +5 -4
  286. package/dist/js/internal/components/navigationRail.mjs +3 -2
  287. package/dist/js/internal/components/particles.mjs +3 -2
  288. package/dist/js/internal/components/pieChart.mjs +4 -3
  289. package/dist/js/internal/components/pullToRefresh.mjs +9 -0
  290. package/dist/js/internal/components/pullToRefresh.mjs.map +7 -0
  291. package/dist/js/internal/components/questionnaire.mjs +3 -3
  292. package/dist/js/internal/components/radarChart.mjs +4 -3
  293. package/dist/js/internal/components/radialChart.mjs +4 -3
  294. package/dist/js/internal/components/registry.mjs +60 -41
  295. package/dist/js/internal/components/richTextEditor.mjs +3 -3
  296. package/dist/js/internal/components/sankeyChart.mjs +10 -0
  297. package/dist/js/internal/components/sankeyChart.mjs.map +7 -0
  298. package/dist/js/internal/components/scatterChart.mjs +10 -0
  299. package/dist/js/internal/components/scatterChart.mjs.map +7 -0
  300. package/dist/js/internal/components/scrollspy.mjs +3 -2
  301. package/dist/js/internal/components/select.mjs +5 -4
  302. package/dist/js/internal/components/showMore.mjs +9 -0
  303. package/dist/js/internal/components/showMore.mjs.map +7 -0
  304. package/dist/js/internal/components/slider.mjs +3 -3
  305. package/dist/js/internal/components/snackbar.mjs +2 -2
  306. package/dist/js/internal/components/swipeActions.mjs +9 -0
  307. package/dist/js/internal/components/swipeActions.mjs.map +7 -0
  308. package/dist/js/internal/components/tabs.mjs +3 -4
  309. package/dist/js/internal/components/timepicker.mjs +5 -4
  310. package/dist/js/internal/components/tooltip.mjs +3 -3
  311. package/dist/js/internal/components/treeSelect.mjs +14 -0
  312. package/dist/js/internal/components/treeSelect.mjs.map +7 -0
  313. package/dist/js/internal/components/treemapChart.mjs +10 -0
  314. package/dist/js/internal/components/treemapChart.mjs.map +7 -0
  315. package/dist/js/internal/core/component.mjs +6 -3
  316. package/dist/js/internal/core/formControl.mjs +12 -0
  317. package/dist/js/internal/core/formControl.mjs.map +7 -0
  318. package/dist/js/internal/core/imageURL.mjs +7 -0
  319. package/dist/js/internal/core/imageURL.mjs.map +7 -0
  320. package/dist/js/internal/core/spring.mjs +11 -0
  321. package/dist/js/internal/core/spring.mjs.map +7 -0
  322. package/dist/js/internal/core/utils.mjs +21 -3
  323. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  324. package/dist/js/internal/plugins/modalDisplayPlugin.mjs +13 -0
  325. package/dist/js/internal/plugins/modalDisplayPlugin.mjs.map +7 -0
  326. package/dist/js/modular.mjs +172 -69
  327. package/dist/types/behaviors/bottomSheets.d.ts +23 -5
  328. package/dist/types/behaviors/copy.d.ts +18 -0
  329. package/dist/types/behaviors/dataTables.d.ts +125 -0
  330. package/dist/types/behaviors/dialogs.d.ts +27 -1
  331. package/dist/types/behaviors/forms.d.ts +70 -4
  332. package/dist/types/behaviors/imageCompare.d.ts +13 -0
  333. package/dist/types/behaviors/lists.d.ts +12 -0
  334. package/dist/types/behaviors/paneResize.d.ts +29 -0
  335. package/dist/types/behaviors/sheetDrag.d.ts +18 -0
  336. package/dist/types/behaviors/sideSheets.d.ts +1 -1
  337. package/dist/types/behaviors/sortable.d.ts +28 -0
  338. package/dist/types/behaviors/theme.d.ts +22 -0
  339. package/dist/types/behaviors/tour.d.ts +36 -0
  340. package/dist/types/behaviors/transferList.d.ts +53 -0
  341. package/dist/types/components/appBar.d.ts +5 -6
  342. package/dist/types/components/autocomplete.d.ts +105 -20
  343. package/dist/types/components/backToTop.d.ts +36 -0
  344. package/dist/types/components/barChart.d.ts +3 -6
  345. package/dist/types/components/buttonGroup.d.ts +2 -4
  346. package/dist/types/components/buttons.d.ts +5 -5
  347. package/dist/types/components/cards.d.ts +3 -16
  348. package/dist/types/components/carousel.d.ts +16 -15
  349. package/dist/types/components/cascader.d.ts +130 -0
  350. package/dist/types/components/characterCounter.d.ts +2 -15
  351. package/dist/types/components/chips.d.ts +80 -19
  352. package/dist/types/components/colorPicker.d.ts +56 -0
  353. package/dist/types/components/columnChart.d.ts +23 -10
  354. package/dist/types/components/commandPalette.d.ts +11 -16
  355. package/dist/types/components/confetti.d.ts +2 -4
  356. package/dist/types/components/currencyInput.d.ts +60 -0
  357. package/dist/types/components/datepicker.d.ts +107 -56
  358. package/dist/types/components/expandingCard.d.ts +4 -6
  359. package/dist/types/components/funnelChart.d.ts +35 -0
  360. package/dist/types/components/heatmapChart.d.ts +42 -8
  361. package/dist/types/components/hoverCard.d.ts +59 -0
  362. package/dist/types/components/index.d.ts +16 -1
  363. package/dist/types/components/inputMask.d.ts +28 -0
  364. package/dist/types/components/keypad.d.ts +38 -6
  365. package/dist/types/components/lightbox.d.ts +14 -20
  366. package/dist/types/components/lineChart.d.ts +212 -12
  367. package/dist/types/components/loadingOverlay.d.ts +42 -0
  368. package/dist/types/components/mapView.d.ts +138 -27
  369. package/dist/types/components/menu.d.ts +74 -22
  370. package/dist/types/components/menubar.d.ts +37 -0
  371. package/dist/types/components/messageScroller.d.ts +2 -14
  372. package/dist/types/components/mixedChart.d.ts +15 -6
  373. package/dist/types/components/navigationRail.d.ts +16 -5
  374. package/dist/types/components/particles.d.ts +22 -5
  375. package/dist/types/components/pieChart.d.ts +33 -9
  376. package/dist/types/components/pullToRefresh.d.ts +80 -0
  377. package/dist/types/components/questionnaire.d.ts +58 -16
  378. package/dist/types/components/radarChart.d.ts +10 -6
  379. package/dist/types/components/radialChart.d.ts +58 -7
  380. package/dist/types/components/registry.d.ts +73 -3
  381. package/dist/types/components/richTextEditor.d.ts +45 -22
  382. package/dist/types/components/sankeyChart.d.ts +72 -0
  383. package/dist/types/components/scatterChart.d.ts +102 -0
  384. package/dist/types/components/scrollspy.d.ts +3 -5
  385. package/dist/types/components/select.d.ts +44 -33
  386. package/dist/types/components/showMore.d.ts +53 -0
  387. package/dist/types/components/slider.d.ts +2 -15
  388. package/dist/types/components/snackbar.d.ts +68 -1
  389. package/dist/types/components/swipeActions.d.ts +81 -0
  390. package/dist/types/components/tabs.d.ts +92 -30
  391. package/dist/types/components/timepicker.d.ts +128 -27
  392. package/dist/types/components/tooltip.d.ts +57 -21
  393. package/dist/types/components/treeSelect.d.ts +106 -0
  394. package/dist/types/components/treemapChart.d.ts +56 -0
  395. package/dist/types/core/component.d.ts +49 -25
  396. package/dist/types/core/formControl.d.ts +21 -0
  397. package/dist/types/core/imageURL.d.ts +2 -0
  398. package/dist/types/core/spring.d.ts +20 -0
  399. package/dist/types/core/utils.d.ts +123 -72
  400. package/dist/types/modular.d.ts +33 -1
  401. package/dist/types/plugins/dockedDisplayPlugin.d.ts +10 -8
  402. package/dist/types/plugins/modalDisplayPlugin.d.ts +39 -0
  403. package/package.json +17 -13
  404. package/src/sass/README.md +27 -18
  405. package/src/sass/abstracts/_elevation.scss +13 -7
  406. package/src/sass/abstracts/_index.scss +1 -0
  407. package/src/sass/abstracts/_mixins.scss +864 -78
  408. package/src/sass/abstracts/_spring.scss +63 -0
  409. package/src/sass/abstracts/_variables.scss +64 -21
  410. package/src/sass/base/_fonts.scss +61 -48
  411. package/src/sass/base/_global.scss +104 -24
  412. package/src/sass/base/_index.scss +2 -0
  413. package/src/sass/base/_normalize.scss +59 -114
  414. package/src/sass/base/_print.scss +21 -0
  415. package/src/sass/base/_prose.scss +68 -0
  416. package/src/sass/base/_typography.scss +9 -5
  417. package/src/sass/components/_accordion.scss +10 -19
  418. package/src/sass/components/_alert.scss +102 -0
  419. package/src/sass/components/_aura.scss +9 -3
  420. package/src/sass/components/_avatar.scss +3 -3
  421. package/src/sass/components/_back-to-top.scss +38 -0
  422. package/src/sass/components/_badges.scss +6 -5
  423. package/src/sass/components/_bar-chart.scss +31 -90
  424. package/src/sass/components/_bottom-sheet.scss +51 -16
  425. package/src/sass/components/_breadcrumb.scss +8 -7
  426. package/src/sass/components/_button-groups.scss +30 -63
  427. package/src/sass/components/_buttons.scss +137 -94
  428. package/src/sass/components/_calendar.scss +244 -0
  429. package/src/sass/components/_cards.scss +36 -44
  430. package/src/sass/components/_carousel.scss +37 -113
  431. package/src/sass/components/_cascader.scss +131 -0
  432. package/src/sass/components/_chips.scss +36 -46
  433. package/src/sass/components/_column-chart.scss +15 -26
  434. package/src/sass/components/_command-palette.scss +4 -7
  435. package/src/sass/components/_confetti.scss +1 -4
  436. package/src/sass/components/_countdown.scss +1 -1
  437. package/src/sass/components/_data-table.scss +172 -25
  438. package/src/sass/components/_datepicker.scss +54 -40
  439. package/src/sass/components/_description-list.scss +85 -0
  440. package/src/sass/components/_dialog.scss +48 -55
  441. package/src/sass/components/_docked-display.scss +1 -3
  442. package/src/sass/components/_drag-handle.scss +16 -20
  443. package/src/sass/components/_expanding-card.scss +21 -14
  444. package/src/sass/components/_fab-menu.scss +43 -39
  445. package/src/sass/components/_funnel-chart.scss +63 -0
  446. package/src/sass/components/_heatmap-chart.scss +114 -29
  447. package/src/sass/components/_icon-buttons.scss +8 -11
  448. package/src/sass/components/_icons-material-design.scss +2 -2
  449. package/src/sass/components/_image-compare.scss +108 -0
  450. package/src/sass/components/_index.scss +20 -0
  451. package/src/sass/components/_keypad.scss +39 -19
  452. package/src/sass/components/_kpi.scss +6 -11
  453. package/src/sass/components/_lightbox.scss +24 -13
  454. package/src/sass/components/_line-chart.scss +9 -63
  455. package/src/sass/components/_list.scss +59 -14
  456. package/src/sass/components/_loading-indicator.scss +1 -0
  457. package/src/sass/components/_loading-overlay.scss +105 -0
  458. package/src/sass/components/_map.scss +37 -11
  459. package/src/sass/components/_marquee.scss +4 -3
  460. package/src/sass/components/_mega-menu.scss +128 -0
  461. package/src/sass/components/_menu.scss +146 -127
  462. package/src/sass/components/_menubar.scss +47 -0
  463. package/src/sass/components/_message-scroller.scss +2 -2
  464. package/src/sass/components/_message.scss +3 -3
  465. package/src/sass/components/_mixed-chart.scss +27 -35
  466. package/src/sass/components/_modal-display.scss +21 -0
  467. package/src/sass/components/_navbar.scss +45 -36
  468. package/src/sass/components/_navigation-bar.scss +12 -77
  469. package/src/sass/components/_navigation-rail.scss +161 -92
  470. package/src/sass/components/_org-chart.scss +192 -0
  471. package/src/sass/components/_page-footer.scss +2 -4
  472. package/src/sass/components/_pagination.scss +9 -27
  473. package/src/sass/components/_panes.scss +35 -42
  474. package/src/sass/components/_particles.scss +1 -4
  475. package/src/sass/components/_pie-chart.scss +86 -68
  476. package/src/sass/components/_popover.scss +18 -5
  477. package/src/sass/components/_progress.scss +183 -44
  478. package/src/sass/components/_pull-to-refresh.scss +90 -0
  479. package/src/sass/components/_questionnaire.scss +74 -3
  480. package/src/sass/components/_radar-chart.scss +40 -42
  481. package/src/sass/components/_radial-chart.scss +108 -46
  482. package/src/sass/components/_rich-text-editor.scss +2 -2
  483. package/src/sass/components/_sankey-chart.scss +91 -0
  484. package/src/sass/components/_scatter-chart.scss +144 -0
  485. package/src/sass/components/_scrim.scss +0 -2
  486. package/src/sass/components/_scrollspy.scss +0 -2
  487. package/src/sass/components/_search.scss +27 -26
  488. package/src/sass/components/_show-more.scss +8 -0
  489. package/src/sass/components/_side-sheet.scss +32 -51
  490. package/src/sass/components/_skeleton.scss +26 -19
  491. package/src/sass/components/_snackbar.scss +25 -21
  492. package/src/sass/components/_split-button.scss +5 -5
  493. package/src/sass/components/_stat.scss +3 -8
  494. package/src/sass/components/_stepper.scss +1 -1
  495. package/src/sass/components/_swipe-actions.scss +71 -0
  496. package/src/sass/components/_table_of_contents.scss +1 -3
  497. package/src/sass/components/_tabs.scss +49 -46
  498. package/src/sass/components/_timeline.scss +12 -12
  499. package/src/sass/components/_timepicker.scss +111 -79
  500. package/src/sass/components/_toolbar.scss +36 -47
  501. package/src/sass/components/_tooltip.scss +25 -12
  502. package/src/sass/components/_tour.scss +89 -0
  503. package/src/sass/components/_transfer-list.scss +73 -0
  504. package/src/sass/components/_transitions.scss +4 -4
  505. package/src/sass/components/_tree.scss +7 -32
  506. package/src/sass/components/_treemap-chart.scss +98 -0
  507. package/src/sass/components/forms/_checkboxes.scss +107 -44
  508. package/src/sass/components/forms/_color-picker.scss +135 -0
  509. package/src/sass/components/forms/_color-swatches.scss +85 -0
  510. package/src/sass/components/forms/_drop-zone.scss +16 -13
  511. package/src/sass/components/forms/_fieldset.scss +4 -7
  512. package/src/sass/components/forms/_file-input.scss +12 -8
  513. package/src/sass/components/forms/_index.scss +3 -1
  514. package/src/sass/components/forms/_input-fields.scss +271 -90
  515. package/src/sass/components/forms/_radio-buttons.scss +34 -117
  516. package/src/sass/components/forms/_rating.scss +2 -32
  517. package/src/sass/components/forms/_select.scss +198 -20
  518. package/src/sass/components/forms/_slider.scss +92 -98
  519. package/src/sass/components/forms/_switches.scss +62 -180
  520. package/src/sass/custom.scss +10 -1
  521. package/src/sass/expressive.scss +3 -63
  522. package/src/sass/tokens/_contrast.scss +94 -0
  523. package/src/sass/tokens/_elevation.scss +16 -0
  524. package/src/sass/tokens/_index.scss +5 -0
  525. package/src/sass/tokens/_motion.scss +109 -0
  526. package/src/sass/tokens/_reference.scss +72 -141
  527. package/src/sass/tokens/_shape.scss +38 -0
  528. package/src/sass/tokens/_stacking.scss +27 -0
  529. package/src/sass/tokens/_state.scss +0 -2
  530. package/src/sass/tokens/_theme.scss +10 -1
  531. package/src/sass/tokens/_vibrant.scss +2 -5
  532. package/src/sass/utilities/_defer-render.scss +17 -0
  533. package/src/sass/utilities/_helpers.scss +184 -27
  534. package/src/sass/utilities/_index.scss +1 -0
  535. package/src/sass/utilities/_scroll-area.scss +0 -2
  536. package/src/sass/utilities/_spacing.scss +52 -34
  537. package/src/sass/utilities/_typescale.scss +8 -1
  538. package/src/sass/utilities/_visibility.scss +46 -77
  539. package/src/sass/utilities/_z-depth.scss +7 -4
  540. package/dist/js/chunks/chunk-33QVDDGR.mjs +0 -270
  541. package/dist/js/chunks/chunk-33QVDDGR.mjs.map +0 -7
  542. package/dist/js/chunks/chunk-45FER6RI.mjs +0 -59
  543. package/dist/js/chunks/chunk-45FER6RI.mjs.map +0 -7
  544. package/dist/js/chunks/chunk-5CEAOLUA.mjs.map +0 -7
  545. package/dist/js/chunks/chunk-6VATUZC6.mjs +0 -295
  546. package/dist/js/chunks/chunk-6VATUZC6.mjs.map +0 -7
  547. package/dist/js/chunks/chunk-74MXKKLN.mjs.map +0 -7
  548. package/dist/js/chunks/chunk-AIURVCG6.mjs +0 -55
  549. package/dist/js/chunks/chunk-AIURVCG6.mjs.map +0 -7
  550. package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +0 -7
  551. package/dist/js/chunks/chunk-C6CHEWYP.mjs.map +0 -7
  552. package/dist/js/chunks/chunk-CK2XCICY.mjs.map +0 -7
  553. package/dist/js/chunks/chunk-CXXM2L4F.mjs +0 -344
  554. package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +0 -7
  555. package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +0 -7
  556. package/dist/js/chunks/chunk-FM5CZOUB.mjs.map +0 -7
  557. package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +0 -7
  558. package/dist/js/chunks/chunk-K3HZMFMD.mjs +0 -135
  559. package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +0 -7
  560. package/dist/js/chunks/chunk-KHXZ2A4K.mjs.map +0 -7
  561. package/dist/js/chunks/chunk-KQACNQ22.mjs +0 -7
  562. package/dist/js/chunks/chunk-KQACNQ22.mjs.map +0 -7
  563. package/dist/js/chunks/chunk-KUFHW3DS.mjs.map +0 -7
  564. package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +0 -7
  565. package/dist/js/chunks/chunk-L27Q6ZMI.mjs.map +0 -7
  566. package/dist/js/chunks/chunk-LQWUDNHZ.mjs.map +0 -7
  567. package/dist/js/chunks/chunk-M372EDXD.mjs +0 -322
  568. package/dist/js/chunks/chunk-M372EDXD.mjs.map +0 -7
  569. package/dist/js/chunks/chunk-M3MURWMB.mjs +0 -82
  570. package/dist/js/chunks/chunk-M3MURWMB.mjs.map +0 -7
  571. package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +0 -7
  572. package/dist/js/chunks/chunk-OWG3LMUL.mjs +0 -169
  573. package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +0 -7
  574. package/dist/js/chunks/chunk-PD6HYHAE.mjs +0 -48
  575. package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +0 -7
  576. package/dist/js/chunks/chunk-PDG64UHF.mjs.map +0 -7
  577. package/dist/js/chunks/chunk-PO3AXVR3.mjs +0 -546
  578. package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +0 -7
  579. package/dist/js/chunks/chunk-QYGK36OG.mjs +0 -181
  580. package/dist/js/chunks/chunk-QYGK36OG.mjs.map +0 -7
  581. package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +0 -7
  582. package/dist/js/chunks/chunk-SMY7GJSS.mjs.map +0 -7
  583. package/dist/js/chunks/chunk-TCCA2HDG.mjs +0 -414
  584. package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +0 -7
  585. package/dist/js/chunks/chunk-TSZYSW7F.mjs.map +0 -7
  586. package/dist/js/chunks/chunk-UAZSDUVP.mjs +0 -90
  587. package/dist/js/chunks/chunk-UAZSDUVP.mjs.map +0 -7
  588. package/dist/js/chunks/chunk-UBRZZWRA.mjs +0 -127
  589. package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +0 -7
  590. package/dist/js/chunks/chunk-UCOE7ZDL.mjs +0 -287
  591. package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +0 -7
  592. package/dist/js/chunks/chunk-UETTGDLI.mjs.map +0 -7
  593. package/dist/js/chunks/chunk-UNCRDLP6.mjs +0 -136
  594. package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +0 -7
  595. package/dist/js/chunks/chunk-VGNYF6FB.mjs.map +0 -7
  596. package/dist/js/chunks/chunk-VGPGBNGL.mjs +0 -68
  597. package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +0 -7
  598. package/dist/js/chunks/chunk-VKAUVTQY.mjs +0 -1
  599. package/dist/js/chunks/chunk-VM4FTS7L.mjs +0 -48
  600. package/dist/js/chunks/chunk-VM4FTS7L.mjs.map +0 -7
  601. package/dist/js/chunks/chunk-WDK4T63U.mjs.map +0 -7
  602. package/dist/js/chunks/chunk-WOCCTVUF.mjs +0 -185
  603. package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +0 -7
  604. package/dist/js/chunks/chunk-WQYN5L4E.mjs +0 -107
  605. package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +0 -7
  606. package/dist/js/chunks/chunk-X4ISMKE2.mjs.map +0 -7
  607. package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +0 -7
  608. package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +0 -7
  609. /package/dist/js/chunks/{chunk-VKAUVTQY.mjs.map → chunk-GNRSYMVH.mjs.map} +0 -0
@@ -0,0 +1,299 @@
1
+ // src/ts/core/utils.ts
2
+ var fit = (start, size, view, offset) => start < offset ? offset : start + size > view - offset ? view - size : start;
3
+ function restoreAttribute(el, name, value) {
4
+ if (value === null) el.removeAttribute(name);
5
+ else el.setAttribute(name, value);
6
+ }
7
+ function numberValue(raw) {
8
+ const text = raw.replace(/−/g, "-").replace(/[\s%\p{Sc}]/gu, "");
9
+ if (!/^[+-]?(\d{1,3}(,\d{3})+|\d+)?(\.\d+)?(e[+-]?\d+)?$/i.test(text)) return null;
10
+ const value = parseFloat(text.replace(/,/g, ""));
11
+ return Number.isFinite(value) ? value : null;
12
+ }
13
+ function formEventScope(el) {
14
+ const root = el.getRootNode();
15
+ return "host" in root ? root : el.ownerDocument;
16
+ }
17
+ function afterFormReset(el, restored, signal) {
18
+ const handled = /* @__PURE__ */ new WeakSet();
19
+ const onReset = (e) => {
20
+ if (e.target !== el.form || handled.has(e)) return;
21
+ handled.add(e);
22
+ setTimeout(() => signal.aborted || e.defaultPrevented || restored());
23
+ };
24
+ const bind = () => {
25
+ for (const target of [formEventScope(el), el.form]) target?.addEventListener("reset", onReset, { capture: true, signal });
26
+ };
27
+ bind();
28
+ return bind;
29
+ }
30
+ function afterAnyFormReset(restored) {
31
+ document.addEventListener("reset", (e) => {
32
+ const form = e.target;
33
+ if (form instanceof HTMLFormElement) setTimeout(() => e.defaultPrevented || restored(form));
34
+ }, true);
35
+ }
36
+ function deepActiveElement(root) {
37
+ let active = root.activeElement;
38
+ while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
39
+ return active;
40
+ }
41
+ function footerButton(parent, text, className, onClick, visible = true) {
42
+ const button = document.createElement("button");
43
+ button.className = `${className} text`;
44
+ button.style.visibility = visible ? "visible" : "hidden";
45
+ button.type = "button";
46
+ button.tabIndex = visible ? 0 : -1;
47
+ button.innerText = text ?? "";
48
+ button.addEventListener("click", onClick);
49
+ parent.append(button);
50
+ }
51
+ function pickerFooter(footer, { i18n, showClearBtn, autoSubmit }, clearClass, onClear, onConfirm, onCancel) {
52
+ footerButton(footer, i18n.clear, clearClass, onClear, showClearBtn);
53
+ if (autoSubmit) return;
54
+ const buttons = document.createElement("div");
55
+ buttons.classList.add("confirmation-btns");
56
+ footer.append(buttons);
57
+ footerButton(buttons, i18n.cancel, "btn-cancel", onCancel);
58
+ footerButton(buttons, i18n.done, "btn-confirm", onConfirm);
59
+ }
60
+ function controllerFor(node) {
61
+ return new (node.ownerDocument?.defaultView ?? window).AbortController();
62
+ }
63
+ function svgNode(name, attributes = {}) {
64
+ const element = document.createElementNS("http://www.w3.org/2000/svg", name);
65
+ for (const key in attributes) element.setAttribute(key, attributes[key]);
66
+ return element;
67
+ }
68
+ var Utils = class _Utils {
69
+ /**
70
+ * Whether a keydown belongs to an IME composition, such as the Enter that
71
+ * confirms a candidate. Safari reports `isComposing` false for that Enter,
72
+ * so keyCode 229 covers it.
73
+ */
74
+ static isComposing(e) {
75
+ return e.isComposing || e.keyCode === 229;
76
+ }
77
+ /**
78
+ * `handler`, skipped for every key of an IME composition: while the user
79
+ * picks a candidate, Enter, the arrows and Escape belong to the IME.
80
+ */
81
+ static ignoringComposition(handler) {
82
+ return (e) => {
83
+ if (!_Utils.isComposing(e)) handler(e);
84
+ };
85
+ }
86
+ /**
87
+ * Run `callback` once the document is parsed.
88
+ *
89
+ * The document-level behaviors all used a bare DOMContentLoaded listener,
90
+ * which never fires if the bundle is loaded after that event - an async or
91
+ * deferred script tag, or a dynamic import. Checking readyState first covers
92
+ * both orders.
93
+ */
94
+ static onDocumentReady(callback) {
95
+ if (typeof document === "undefined") return;
96
+ if (document.readyState === "loading") {
97
+ document.addEventListener("DOMContentLoaded", callback, { once: true });
98
+ } else {
99
+ callback();
100
+ }
101
+ }
102
+ /**
103
+ * The language an element is written in, from the nearest `lang`, or
104
+ * undefined without one or for a tag the browser does not know.
105
+ */
106
+ static locale(el) {
107
+ let [node, lang] = [el, void 0];
108
+ while (node && lang === void 0) {
109
+ lang = node.closest("[lang]")?.lang;
110
+ node = node.getRootNode().host;
111
+ }
112
+ try {
113
+ return lang ? Intl.getCanonicalLocales(lang)[0] : void 0;
114
+ } catch {
115
+ return void 0;
116
+ }
117
+ }
118
+ /**
119
+ * Generates a unique string identifier. Every caller prefixes the result and
120
+ * uses it as an element id, and a UUID is valid in that position.
121
+ *
122
+ * `randomUUID` is exposed only in secure contexts, and a dev server on a
123
+ * plain-HTTP LAN address - the usual way a page is opened on a phone - is
124
+ * not one. Without the fallback every component that stamps an id would
125
+ * throw there. The ids only have to be unique within one document, so the
126
+ * fallback does not need to be cryptographic.
127
+ */
128
+ static guid() {
129
+ return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
130
+ }
131
+ /**
132
+ * Where an element created at runtime has to be appended to stay in the same
133
+ * tree as `el`. A stylesheet adopted into a shadow root cannot match a node
134
+ * in the document, so a portal that lands on `document.body` is unstyled
135
+ * whenever its origin lives in a shadow root (adr/0002).
136
+ *
137
+ * Light-DOM elements still get `document.body`, which is what escapes an
138
+ * ancestor's `overflow: hidden` and stacking context. Inside a shadow root
139
+ * both hazards come back: the host's own ancestors still form the containing
140
+ * block, so a transformed ancestor re-anchors `position: fixed` and a
141
+ * positioned one re-anchors `position: absolute`.
142
+ */
143
+ static portalRoot(el) {
144
+ const root = el.getRootNode();
145
+ return root.host ? root : document.body;
146
+ }
147
+ /**
148
+ * `getElementById` against the tree `el` lives in. The mirror of
149
+ * `portalRoot`: an id in a shadow root is invisible to
150
+ * `document.getElementById`, so a trigger and its target inside the same
151
+ * root could not find each other at all.
152
+ *
153
+ * Falls back to the document for a detached `el`, whose root is a plain
154
+ * element with no lookup of its own.
155
+ */
156
+ static getElementById(el, id) {
157
+ const root = el.getRootNode();
158
+ return root.getElementById ? root.getElementById(id) : document.getElementById(id);
159
+ }
160
+ /**
161
+ * `querySelector` against the tree `el` lives in, then the document, so a
162
+ * selector option finds an element in the same shadow root and still finds
163
+ * one outside it, such as `body`.
164
+ */
165
+ static querySelector(el, selector) {
166
+ const root = el.getRootNode();
167
+ return "getElementById" in root && root.querySelector(selector) || document.querySelector(selector);
168
+ }
169
+ /**
170
+ * Adds or removes one name in an element's inline `anchor-name` list. A
171
+ * trigger can anchor a Tooltip and a Menu at once, and writing the whole
172
+ * property let the last writer, or the first to be destroyed, wipe the other.
173
+ */
174
+ static setAnchorName(el, name, on) {
175
+ const names = el.style.getPropertyValue("anchor-name").split(",").map((n) => n.trim()).filter((n) => n && n !== "none" && n !== name);
176
+ if (on) names.push(name);
177
+ if (names.length) el.style.setProperty("anchor-name", names.join(", "));
178
+ else el.style.removeProperty("anchor-name");
179
+ }
180
+ /**
181
+ * Fires `expressive:<type>` from `el`. It bubbles and crosses shadow roots,
182
+ * so a page can listen on the element, an ancestor or the document. A
183
+ * `cancelable` event returns false once a listener calls preventDefault().
184
+ */
185
+ static emit(el, type, detail, cancelable = false) {
186
+ return el.dispatchEvent(new CustomEvent(`expressive:${type}`, { bubbles: true, composed: true, cancelable, detail }));
187
+ }
188
+ /**
189
+ * The element an event really started on, for a listener on the document.
190
+ * There `event.target` is retargeted to the shadow host, so delegation that
191
+ * reads it never sees anything inside an open shadow root. A closed root
192
+ * keeps its inside private and still yields the host.
193
+ */
194
+ static eventTarget(event) {
195
+ const target = event.composedPath()[0] ?? event.target;
196
+ return target instanceof Element ? target : null;
197
+ }
198
+ /** Whether a key was pressed without Alt, Ctrl or Meta, which belong to the browser and the system. */
199
+ static plainKey(e) {
200
+ return !(e.altKey || e.ctrlKey || e.metaKey);
201
+ }
202
+ /** Where a key moves from `index` among `count` items: by `steps`, or to an end for Home and End. NaN for any other key. */
203
+ static _keyIndex(key, index, count, steps) {
204
+ if (key === "Home") return 0;
205
+ if (key === "End") return count - 1;
206
+ return index + (steps[key] ?? NaN);
207
+ }
208
+ /**
209
+ * The item a key moves focus to, from the focused one among `items`: by
210
+ * the offset `steps` gives the key, or to the first or last for Home and
211
+ * End. Disabled items are skipped. Undefined for other keys, for a key
212
+ * with a modifier, when focus is on none of the items, and past either end
213
+ * unless `wrap`.
214
+ */
215
+ static focusTarget(items, e, steps, wrap = false) {
216
+ const enabled = items.filter((item) => !item.matches(':disabled, [aria-disabled="true"], .disabled'));
217
+ const index = enabled.indexOf(_Utils.eventTarget(e));
218
+ if (index < 0 || !_Utils.plainKey(e)) return void 0;
219
+ const to = _Utils._keyIndex(e.key, index, enabled.length, steps);
220
+ return enabled[wrap ? (to + enabled.length) % enabled.length : to];
221
+ }
222
+ /**
223
+ * Whether focus is on or inside any of `els`, read from each element's own
224
+ * root. A document listener cannot tell from `composedPath()` when the
225
+ * element sits in a closed shadow root, but the element's root still knows
226
+ * what has focus.
227
+ */
228
+ static focusIsIn(...els) {
229
+ return els.some((el) => {
230
+ const active = el && el.getRootNode().activeElement;
231
+ return !!active && el.contains(active);
232
+ });
233
+ }
234
+ /**
235
+ * `closest()` for a document listener: the nearest element on the event's
236
+ * composed path that matches `selector`. Unlike `eventTarget(e).closest()`
237
+ * it climbs out of shadow roots too, so a press on a shadow-root icon inside
238
+ * a light-DOM button still finds the button.
239
+ */
240
+ static closestInPath(event, selector) {
241
+ for (const node of event.composedPath()) {
242
+ if (node instanceof Element && node.matches(selector)) return node;
243
+ }
244
+ return null;
245
+ }
246
+ /**
247
+ * Retrieves target element id from trigger.
248
+ * @param trigger Trigger element.
249
+ */
250
+ static getIdFromTrigger(trigger) {
251
+ return trigger.dataset.target || (trigger.getAttribute("href")?.slice(1) ?? "");
252
+ }
253
+ /**
254
+ * Writes document coordinates as `top`/`left` on an absolutely positioned
255
+ * element. A static body uses document coordinates; positioned parents,
256
+ * such as a shadow host, use their padding edge, including borders and
257
+ * local scrolling.
258
+ */
259
+ static _placeInOffsetParent(el, coordinates) {
260
+ let { x, y } = coordinates;
261
+ const parent = el.offsetParent;
262
+ if (parent && (parent !== document.body || getComputedStyle(parent).position !== "static")) {
263
+ const rect = parent.getBoundingClientRect();
264
+ const root = parent === document.scrollingElement;
265
+ x -= rect.left + window.scrollX + parent.clientLeft - (root ? 0 : parent.scrollLeft);
266
+ y -= rect.top + window.scrollY + parent.clientTop - (root ? 0 : parent.scrollTop);
267
+ }
268
+ el.style.top = y + "px";
269
+ el.style.left = x + "px";
270
+ }
271
+ /**
272
+ * Moves document coordinates so a `width` by `height` box stays in the
273
+ * viewport. A box past the left or top edge, or within `offset` of it,
274
+ * starts `offset` in; a box past the right or bottom edge, or within
275
+ * `offset` of it, ends at that edge. `offset` is the margin plus the slide
276
+ * distance, or minus it for right alignment.
277
+ */
278
+ static _repositionWithinScreen(x, y, width, height, margin, transitionMovement, align) {
279
+ const offset = margin + (align === "right" ? -transitionMovement : transitionMovement);
280
+ return {
281
+ x: window.scrollX + fit(x - window.scrollX, width, window.innerWidth, offset),
282
+ y: window.scrollY + fit(y - window.scrollY, height, window.innerHeight, offset)
283
+ };
284
+ }
285
+ };
286
+
287
+ export {
288
+ restoreAttribute,
289
+ numberValue,
290
+ formEventScope,
291
+ afterFormReset,
292
+ afterAnyFormReset,
293
+ deepActiveElement,
294
+ pickerFooter,
295
+ controllerFor,
296
+ svgNode,
297
+ Utils
298
+ };
299
+ //# sourceMappingURL=chunk-67UNY7RH.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/core/utils.ts"],
4
+ "sourcesContent": ["/** One axis of a viewport clamp: `start` moved so `size` fits in `view`. */\nconst fit = (start: number, size: number, view: number, offset: number) =>\n start < offset ? offset : start + size > view - offset ? view - size : start;\n\n/** Sets an attribute, or removes it for null, as when restoring a value read with getAttribute. */\nexport function restoreAttribute(el: Element, name: string, value: string | null) {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * Reads text as one number, which currency or percent signs, grouping commas\n * and a typographic minus may surround, or null for anything else. Charts and\n * data tables read their cells with it.\n */\nexport function numberValue(raw: string): number | null {\n const text = raw.replace(/\u2212/g, '-').replace(/[\\s%\\p{Sc}]/gu, '');\n if (!/^[+-]?(\\d{1,3}(,\\d{3})+|\\d+)?(\\.\\d+)?(e[+-]?\\d+)?$/i.test(text)) return null;\n // The pattern also lets through \"e5\" (NaN) and \"1e400\" (Infinity).\n const value = parseFloat(text.replace(/,/g, ''));\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * Where a field listens for its form's events. Neither formdata nor reset\n * leaves a shadow root, so a field in one listens there. Otherwise the\n * document, so the listener follows the field into another form.\n */\nexport function formEventScope(el: Element): Document | ShadowRoot {\n const root = el.getRootNode() as Document | ShadowRoot;\n return 'host' in root ? root : el.ownerDocument;\n}\n\n/**\n * Runs `restored` after a reset of the field's form. The form restores its\n * fields after the reset event, so it waits a task. It skips a cancelled\n * reset, and a field whose listeners `signal` has removed since.\n *\n * It listens on the field's root, which hears a form the field moves into\n * later, and on the form itself, which still hears it after the form moves\n * into a shadow root. Reset does not leave a shadow root. The returned\n * function binds both again, for a field that moved into another root;\n * listeners already bound are not added twice.\n */\nexport function afterFormReset(\n el: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,\n restored: () => void,\n signal: AbortSignal\n) {\n const handled = new WeakSet<Event>();\n const onReset = (e: Event) => {\n if (e.target !== el.form || handled.has(e)) return;\n handled.add(e);\n setTimeout(() => signal.aborted || e.defaultPrevented || restored());\n };\n const bind = () => {\n for (const target of [formEventScope(el), el.form]) target?.addEventListener('reset', onReset, { capture: true, signal });\n };\n bind();\n return bind;\n}\n\n/**\n * Runs `restored(form)` a task after any form in the document resets, once\n * the form has restored its fields, unless the reset was cancelled. For\n * document-level behaviors; a component bound to one field uses afterFormReset.\n */\nexport function afterAnyFormReset(restored: (form: HTMLFormElement) => void) {\n document.addEventListener('reset', (e) => {\n const form = e.target;\n if (form instanceof HTMLFormElement) setTimeout(() => e.defaultPrevented || restored(form));\n }, true);\n}\n\n/** The focused element, followed down through open shadow roots. */\nexport function deepActiveElement(root: Document | ShadowRoot): Element | null {\n let active = root.activeElement;\n while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;\n return active;\n}\n\n/** A picker footer text button; a hidden one is also out of the tab order. */\nfunction footerButton(parent: HTMLElement, text: string | undefined, className: string, onClick: () => void, visible = true) {\n const button = document.createElement('button');\n button.className = `${className} text`;\n button.style.visibility = visible ? 'visible' : 'hidden';\n button.type = 'button';\n button.tabIndex = visible ? 0 : -1;\n button.innerText = text ?? '';\n button.addEventListener('click', onClick);\n parent.append(button);\n}\n\n/**\n * Fills a picker's footer: a Clear button, hidden unless `showClearBtn`,\n * then Cancel and Done unless the picker writes its value without them.\n */\nexport function pickerFooter(\n footer: HTMLElement,\n { i18n, showClearBtn, autoSubmit }: { i18n: Partial<Record<'clear' | 'cancel' | 'done', string>>; showClearBtn: boolean; autoSubmit: boolean },\n clearClass: string,\n onClear: () => void,\n onConfirm: () => void,\n onCancel: () => void\n) {\n footerButton(footer, i18n.clear, clearClass, onClear, showClearBtn);\n if (autoSubmit) return;\n const buttons = document.createElement('div');\n buttons.classList.add('confirmation-btns');\n footer.append(buttons);\n footerButton(buttons, i18n.cancel, 'btn-cancel', onCancel);\n footerButton(buttons, i18n.done, 'btn-confirm', onConfirm);\n}\n\n/**\n * An AbortController from the window `node` is in. Its signal removes\n * listeners added there, and jsdom rejects a signal from another window.\n */\nexport function controllerFor(node: Node): AbortController {\n return new (node.ownerDocument?.defaultView ?? window).AbortController();\n}\n\n/** An SVG element with its attributes. */\nexport function svgNode(name: string, attributes: Record<string, string> = {}): SVGElement {\n const element = document.createElementNS('http://www.w3.org/2000/svg', name);\n for (const key in attributes) element.setAttribute(key, attributes[key]);\n return element;\n}\n\n/**\n * Class with utilitary functions for global usage.\n */\nexport class Utils {\n /**\n * Whether a keydown belongs to an IME composition, such as the Enter that\n * confirms a candidate. Safari reports `isComposing` false for that Enter,\n * so keyCode 229 covers it.\n */\n static isComposing(e: KeyboardEvent): boolean {\n return e.isComposing || e.keyCode === 229;\n }\n\n /**\n * `handler`, skipped for every key of an IME composition: while the user\n * picks a candidate, Enter, the arrows and Escape belong to the IME.\n */\n static ignoringComposition(handler: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void {\n return (e) => {\n if (!Utils.isComposing(e)) handler(e);\n };\n }\n\n /**\n * Run `callback` once the document is parsed.\n *\n * The document-level behaviors all used a bare DOMContentLoaded listener,\n * which never fires if the bundle is loaded after that event - an async or\n * deferred script tag, or a dynamic import. Checking readyState first covers\n * both orders.\n */\n static onDocumentReady(callback: () => void): void {\n if (typeof document === 'undefined') return;\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', callback, { once: true });\n } else {\n callback();\n }\n }\n\n /**\n * The language an element is written in, from the nearest `lang`, or\n * undefined without one or for a tag the browser does not know.\n */\n static locale(el: Element): string | undefined {\n // Inside a shadow root the language comes from the host's tree, unless\n // something nearer sets one.\n let [node, lang]: [Element | undefined, string | undefined] = [el, undefined];\n while (node && lang === undefined) {\n lang = node.closest<HTMLElement>('[lang]')?.lang;\n node = (node.getRootNode() as ShadowRoot).host;\n }\n try {\n return lang ? Intl.getCanonicalLocales(lang)[0] : undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Generates a unique string identifier. Every caller prefixes the result and\n * uses it as an element id, and a UUID is valid in that position.\n *\n * `randomUUID` is exposed only in secure contexts, and a dev server on a\n * plain-HTTP LAN address - the usual way a page is opened on a phone - is\n * not one. Without the fallback every component that stamps an id would\n * throw there. The ids only have to be unique within one document, so the\n * fallback does not need to be cryptographic.\n */\n static guid(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n );\n }\n\n /**\n * Where an element created at runtime has to be appended to stay in the same\n * tree as `el`. A stylesheet adopted into a shadow root cannot match a node\n * in the document, so a portal that lands on `document.body` is unstyled\n * whenever its origin lives in a shadow root (adr/0002).\n *\n * Light-DOM elements still get `document.body`, which is what escapes an\n * ancestor's `overflow: hidden` and stacking context. Inside a shadow root\n * both hazards come back: the host's own ancestors still form the containing\n * block, so a transformed ancestor re-anchors `position: fixed` and a\n * positioned one re-anchors `position: absolute`.\n */\n static portalRoot(el: Node): HTMLElement | ShadowRoot {\n const root = el.getRootNode() as ShadowRoot;\n // Only a ShadowRoot has a host; a Document or a detached subtree does not.\n return root.host ? root : document.body;\n }\n\n /**\n * `getElementById` against the tree `el` lives in. The mirror of\n * `portalRoot`: an id in a shadow root is invisible to\n * `document.getElementById`, so a trigger and its target inside the same\n * root could not find each other at all.\n *\n * Falls back to the document for a detached `el`, whose root is a plain\n * element with no lookup of its own.\n */\n static getElementById(el: Node, id: string): HTMLElement {\n const root = el.getRootNode() as Document | ShadowRoot;\n return (root.getElementById ? root.getElementById(id) : document.getElementById(id)) as HTMLElement;\n }\n\n /**\n * `querySelector` against the tree `el` lives in, then the document, so a\n * selector option finds an element in the same shadow root and still finds\n * one outside it, such as `body`.\n */\n static querySelector(el: Node, selector: string): HTMLElement | null {\n const root = el.getRootNode() as Document | ShadowRoot;\n return ('getElementById' in root && root.querySelector<HTMLElement>(selector)) || document.querySelector<HTMLElement>(selector);\n }\n\n /**\n * Adds or removes one name in an element's inline `anchor-name` list. A\n * trigger can anchor a Tooltip and a Menu at once, and writing the whole\n * property let the last writer, or the first to be destroyed, wipe the other.\n */\n static setAnchorName(el: HTMLElement, name: string, on: boolean) {\n const names = el.style.getPropertyValue('anchor-name').split(',').map((n) => n.trim())\n .filter((n) => n && n !== 'none' && n !== name);\n if (on) names.push(name);\n if (names.length) el.style.setProperty('anchor-name', names.join(', '));\n else el.style.removeProperty('anchor-name');\n }\n\n /**\n * Fires `expressive:<type>` from `el`. It bubbles and crosses shadow roots,\n * so a page can listen on the element, an ancestor or the document. A\n * `cancelable` event returns false once a listener calls preventDefault().\n */\n static emit(el: Element, type: string, detail?: unknown, cancelable = false) {\n return el.dispatchEvent(new CustomEvent(`expressive:${type}`, { bubbles: true, composed: true, cancelable, detail }));\n }\n\n /**\n * The element an event really started on, for a listener on the document.\n * There `event.target` is retargeted to the shadow host, so delegation that\n * reads it never sees anything inside an open shadow root. A closed root\n * keeps its inside private and still yields the host.\n */\n static eventTarget(event: Event): Element | null {\n const target = event.composedPath()[0] ?? event.target;\n return target instanceof Element ? target : null;\n }\n\n /** Whether a key was pressed without Alt, Ctrl or Meta, which belong to the browser and the system. */\n static plainKey(e: KeyboardEvent): boolean {\n return !(e.altKey || e.ctrlKey || e.metaKey);\n }\n\n /** Where a key moves from `index` among `count` items: by `steps`, or to an end for Home and End. NaN for any other key. */\n static _keyIndex(key: string, index: number, count: number, steps: Record<string, number>) {\n if (key === 'Home') return 0;\n if (key === 'End') return count - 1;\n return index + (steps[key] ?? NaN);\n }\n\n /**\n * The item a key moves focus to, from the focused one among `items`: by\n * the offset `steps` gives the key, or to the first or last for Home and\n * End. Disabled items are skipped. Undefined for other keys, for a key\n * with a modifier, when focus is on none of the items, and past either end\n * unless `wrap`.\n */\n static focusTarget(items: HTMLElement[], e: KeyboardEvent, steps: Record<string, number>, wrap = false): HTMLElement | undefined {\n const enabled = items.filter((item) => !item.matches(':disabled, [aria-disabled=\"true\"], .disabled'));\n const index = enabled.indexOf(Utils.eventTarget(e) as HTMLElement);\n if (index < 0 || !Utils.plainKey(e)) return undefined;\n const to = Utils._keyIndex(e.key, index, enabled.length, steps);\n return enabled[wrap ? (to + enabled.length) % enabled.length : to];\n }\n\n /**\n * Whether focus is on or inside any of `els`, read from each element's own\n * root. A document listener cannot tell from `composedPath()` when the\n * element sits in a closed shadow root, but the element's root still knows\n * what has focus.\n */\n static focusIsIn(...els: (Element | null | undefined)[]): boolean {\n return els.some((el) => {\n const active = el && (el.getRootNode() as Document | ShadowRoot).activeElement;\n return !!active && el.contains(active);\n });\n }\n\n /**\n * `closest()` for a document listener: the nearest element on the event's\n * composed path that matches `selector`. Unlike `eventTarget(e).closest()`\n * it climbs out of shadow roots too, so a press on a shadow-root icon inside\n * a light-DOM button still finds the button.\n */\n static closestInPath<T extends Element = Element>(event: Event, selector: string): T | null {\n for (const node of event.composedPath()) {\n if (node instanceof Element && node.matches(selector)) return node as T;\n }\n return null;\n }\n\n /**\n * Retrieves target element id from trigger.\n * @param trigger Trigger element.\n */\n static getIdFromTrigger(trigger: HTMLElement): string {\n return trigger.dataset.target || (trigger.getAttribute('href')?.slice(1) ?? '');\n }\n\n /**\n * Writes document coordinates as `top`/`left` on an absolutely positioned\n * element. A static body uses document coordinates; positioned parents,\n * such as a shadow host, use their padding edge, including borders and\n * local scrolling.\n */\n static _placeInOffsetParent(el: HTMLElement, coordinates: { x: number; y: number }) {\n let { x, y } = coordinates;\n const parent = el.offsetParent as HTMLElement;\n if (parent && (parent !== document.body || getComputedStyle(parent).position !== 'static')) {\n const rect = parent.getBoundingClientRect();\n const root = parent === document.scrollingElement;\n x -= rect.left + window.scrollX + parent.clientLeft - (root ? 0 : parent.scrollLeft);\n y -= rect.top + window.scrollY + parent.clientTop - (root ? 0 : parent.scrollTop);\n }\n el.style.top = y + 'px';\n el.style.left = x + 'px';\n }\n\n /**\n * Moves document coordinates so a `width` by `height` box stays in the\n * viewport. A box past the left or top edge, or within `offset` of it,\n * starts `offset` in; a box past the right or bottom edge, or within\n * `offset` of it, ends at that edge. `offset` is the margin plus the slide\n * distance, or minus it for right alignment.\n */\n static _repositionWithinScreen(\n x: number,\n y: number,\n width: number,\n height: number,\n margin: number,\n transitionMovement: number,\n align: string\n ) {\n const offset = margin + (align === 'right' ? -transitionMovement : transitionMovement);\n return {\n x: window.scrollX + fit(x - window.scrollX, width, window.innerWidth, offset),\n y: window.scrollY + fit(y - window.scrollY, height, window.innerHeight, offset)\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,97 @@
1
+ import {
2
+ Component
3
+ } from "./chunk-EB2V4OKL.mjs";
4
+ import {
5
+ Utils,
6
+ restoreAttribute
7
+ } from "./chunk-67UNY7RH.mjs";
8
+
9
+ // src/ts/components/appBar.ts
10
+ var _defaults = {};
11
+ var OPEN_KEYS = ["Enter", "ArrowDown"];
12
+ var opensSearch = (e) => OPEN_KEYS.includes(e.key) && Utils.plainKey(e) && !Utils.isComposing(e);
13
+ var AppBar = class extends Component {
14
+ constructor(el, options) {
15
+ super(el, options);
16
+ this._observer = null;
17
+ this._sentinel = null;
18
+ this._input = null;
19
+ this._view = null;
20
+ // The docked view's state before the first open, for destroy() to restore.
21
+ this._restore = null;
22
+ this._onIntersect = (entries) => {
23
+ const entry = entries.at(-1);
24
+ if (!entry) return;
25
+ this.el.classList.toggle(
26
+ "collapsed",
27
+ !entry.isIntersecting && entry.boundingClientRect.top < this.el.getBoundingClientRect().top
28
+ );
29
+ };
30
+ // A docked view opens on focus, like a combobox popup. A full-screen
31
+ // dialog takes over the page, so reaching the field with Tab only focuses
32
+ // it (WCAG 3.2.1); a click, Enter or ArrowDown opens it.
33
+ this._onSearchFocus = () => {
34
+ if (!(this._view instanceof HTMLDialogElement)) this._openSearch();
35
+ };
36
+ this._onSearchKeydown = (e) => {
37
+ if (!opensSearch(e) || !(this._view instanceof HTMLDialogElement)) return;
38
+ e.preventDefault();
39
+ this._openSearch();
40
+ };
41
+ this._openSearch = () => {
42
+ if (this._view instanceof HTMLDialogElement) {
43
+ if (!this._view.open) this._view.showModal();
44
+ return;
45
+ }
46
+ this._restore ?? (this._restore = { hidden: this._view.hidden, expanded: this._input.getAttribute("aria-expanded") });
47
+ this._view.hidden = false;
48
+ this._input.setAttribute("aria-expanded", "true");
49
+ };
50
+ this._setupCollapse();
51
+ this._setupSearch();
52
+ }
53
+ static get defaults() {
54
+ return _defaults;
55
+ }
56
+ destroy() {
57
+ this._observer?.disconnect();
58
+ this._observer = null;
59
+ this._sentinel?.remove();
60
+ this._sentinel = null;
61
+ if (this._restore) {
62
+ this._view.hidden = this._restore.hidden;
63
+ restoreAttribute(this._input, "aria-expanded", this._restore.expanded);
64
+ this._restore = null;
65
+ }
66
+ this.el.classList.remove("collapsed");
67
+ super.destroy();
68
+ }
69
+ _setupCollapse() {
70
+ if (!this.el.classList.contains("medium") && !this.el.classList.contains("large")) {
71
+ return;
72
+ }
73
+ this._sentinel = document.createElement("span");
74
+ this._sentinel.setAttribute("aria-hidden", "true");
75
+ this._sentinel.style.cssText = "display:block;height:0;position:relative;top:-64px;pointer-events:none;visibility:hidden";
76
+ this.el.insertAdjacentElement("afterend", this._sentinel);
77
+ this._observer = new IntersectionObserver(this._onIntersect);
78
+ this._observer.observe(this._sentinel);
79
+ }
80
+ _setupSearch() {
81
+ this._input = this.el.querySelector('input[type="search"]');
82
+ if (!this._input) return;
83
+ const id = this._input.getAttribute("aria-controls");
84
+ this._view = id && Utils.getElementById(this.el, id) || this.el.querySelector(".search-view");
85
+ if (!this._view) return;
86
+ const { signal } = this._events;
87
+ this._input.addEventListener("focus", this._onSearchFocus, { signal });
88
+ this._input.addEventListener("click", this._openSearch, { signal });
89
+ this._input.addEventListener("keydown", this._onSearchKeydown, { signal });
90
+ }
91
+ };
92
+ AppBar.key = "Expressive_AppBar";
93
+
94
+ export {
95
+ AppBar
96
+ };
97
+ //# sourceMappingURL=chunk-7CXNATJS.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/appBar.ts"],
4
+ "sourcesContent": ["import { Component, BaseOptions } from '../core/component';\nimport { Utils, restoreAttribute } from '../core/utils';\n\nconst _defaults: BaseOptions = {};\n// Keys that open a full-screen search view from its field.\nconst OPEN_KEYS = ['Enter', 'ArrowDown'];\n/** Whether a key opens the view. Alt, Ctrl and Meta stay the browser's, and a composing key the IME's. */\nconst opensSearch = (e: KeyboardEvent) => OPEN_KEYS.includes(e.key) && Utils.plainKey(e) && !Utils.isComposing(e);\n\n/**\n * Collapse medium/large flexible app bars on scroll, and open the related\n * search view when the search field in a search app bar is selected.\n *\n * Observation is IntersectionObserver on a sentinel after the header.\n * A scroll listener would re-enter layout on every tick; this does not.\n */\nexport class AppBar extends Component<BaseOptions> {\n private _observer: IntersectionObserver | null = null;\n private _sentinel: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _view: HTMLElement | null = null;\n // The docked view's state before the first open, for destroy() to restore.\n private _restore: { hidden: HTMLElement['hidden']; expanded: string | null } | null = null;\n\n constructor(el: HTMLElement, options: Partial<BaseOptions>) {\n super(el, options);\n this._setupCollapse();\n this._setupSearch();\n }\n\n static get defaults(): BaseOptions {\n return _defaults;\n }\n\n static key = 'Expressive_AppBar';\n\n destroy() {\n this._observer?.disconnect();\n this._observer = null;\n this._sentinel?.remove();\n this._sentinel = null;\n if (this._restore) {\n this._view.hidden = this._restore.hidden;\n restoreAttribute(this._input, 'aria-expanded', this._restore.expanded);\n this._restore = null;\n }\n this.el.classList.remove('collapsed');\n super.destroy();\n }\n\n private _setupCollapse() {\n if (!this.el.classList.contains('medium') && !this.el.classList.contains('large')) {\n return;\n }\n // Collapsing shrinks the header, and scroll anchoring then scrolls the page\n // back by the height it lost. The sentinel follows the header, so it moves\n // with the page and that correction cannot bring it back into view. It sits\n // 64px, the small bar's height, above the header's bottom edge. An expanded\n // bar therefore collapses once the page has scrolled by the height that\n // collapsing removes, and a collapsed bar expands when the page is back at\n // its top. Zero height and no margins keep it out of the layout.\n this._sentinel = document.createElement('span');\n this._sentinel.setAttribute('aria-hidden', 'true');\n this._sentinel.style.cssText =\n 'display:block;height:0;position:relative;top:-64px;pointer-events:none;visibility:hidden';\n this.el.insertAdjacentElement('afterend', this._sentinel);\n this._observer = new IntersectionObserver(this._onIntersect);\n this._observer.observe(this._sentinel);\n }\n\n private _onIntersect = (entries: IntersectionObserverEntry[]) => {\n // The newest: a busy frame can queue several.\n const entry = entries.at(-1);\n if (!entry) return;\n // Collapse only when the sentinel has gone above the pinned header. A\n // sentinel below the viewport would move back into view as the bar shrank,\n // and the bar would switch sizes on every frame.\n this.el.classList.toggle(\n 'collapsed',\n !entry.isIntersecting && entry.boundingClientRect.top < this.el.getBoundingClientRect().top\n );\n };\n\n private _setupSearch() {\n this._input = this.el.querySelector('input[type=\"search\"]');\n if (!this._input) return;\n\n const id = this._input.getAttribute('aria-controls');\n this._view = (id && Utils.getElementById(this.el, id)) || this.el.querySelector('.search-view');\n if (!this._view) return;\n\n const { signal } = this._events;\n this._input.addEventListener('focus', this._onSearchFocus, { signal });\n this._input.addEventListener('click', this._openSearch, { signal });\n this._input.addEventListener('keydown', this._onSearchKeydown, { signal });\n }\n\n // A docked view opens on focus, like a combobox popup. A full-screen\n // dialog takes over the page, so reaching the field with Tab only focuses\n // it (WCAG 3.2.1); a click, Enter or ArrowDown opens it.\n private _onSearchFocus = () => {\n if (!(this._view instanceof HTMLDialogElement)) this._openSearch();\n };\n\n private _onSearchKeydown = (e: KeyboardEvent) => {\n if (!opensSearch(e) || !(this._view instanceof HTMLDialogElement)) return;\n e.preventDefault();\n this._openSearch();\n };\n\n private _openSearch = () => {\n if (this._view instanceof HTMLDialogElement) {\n if (!this._view.open) this._view.showModal();\n return;\n }\n this._restore ??= { hidden: this._view.hidden, expanded: this._input.getAttribute('aria-expanded') };\n this._view.hidden = false;\n this._input.setAttribute('aria-expanded', 'true');\n };\n}\n"],
5
+ "mappings": ";;;;;;;;;AAGA,IAAM,YAAyB,CAAC;AAEhC,IAAM,YAAY,CAAC,SAAS,WAAW;AAEvC,IAAM,cAAc,CAAC,MAAqB,UAAU,SAAS,EAAE,GAAG,KAAK,MAAM,SAAS,CAAC,KAAK,CAAC,MAAM,YAAY,CAAC;AASzG,IAAM,SAAN,cAAqB,UAAuB;AAAA,EAQjD,YAAY,IAAiB,SAA+B;AAC1D,UAAM,IAAI,OAAO;AARnB,SAAQ,YAAyC;AACjD,SAAQ,YAAgC;AACxC,SAAQ,SAAkC;AAC1C,SAAQ,QAA4B;AAEpC;AAAA,SAAQ,WAA8E;AAgDtF,SAAQ,eAAe,CAAC,YAAyC;AAE/D,YAAM,QAAQ,QAAQ,GAAG,EAAE;AAC3B,UAAI,CAAC,MAAO;AAIZ,WAAK,GAAG,UAAU;AAAA,QAChB;AAAA,QACA,CAAC,MAAM,kBAAkB,MAAM,mBAAmB,MAAM,KAAK,GAAG,sBAAsB,EAAE;AAAA,MAC1F;AAAA,IACF;AAmBA;AAAA;AAAA;AAAA,SAAQ,iBAAiB,MAAM;AAC7B,UAAI,EAAE,KAAK,iBAAiB,mBAAoB,MAAK,YAAY;AAAA,IACnE;AAEA,SAAQ,mBAAmB,CAAC,MAAqB;AAC/C,UAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,iBAAiB,mBAAoB;AACnE,QAAE,eAAe;AACjB,WAAK,YAAY;AAAA,IACnB;AAEA,SAAQ,cAAc,MAAM;AAC1B,UAAI,KAAK,iBAAiB,mBAAmB;AAC3C,YAAI,CAAC,KAAK,MAAM,KAAM,MAAK,MAAM,UAAU;AAC3C;AAAA,MACF;AACA,WAAK,aAAL,KAAK,WAAa,EAAE,QAAQ,KAAK,MAAM,QAAQ,UAAU,KAAK,OAAO,aAAa,eAAe,EAAE;AACnG,WAAK,MAAM,SAAS;AACpB,WAAK,OAAO,aAAa,iBAAiB,MAAM;AAAA,IAClD;AA5FE,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,WAAW,WAAwB;AACjC,WAAO;AAAA,EACT;AAAA,EAIA,UAAU;AACR,SAAK,WAAW,WAAW;AAC3B,SAAK,YAAY;AACjB,SAAK,WAAW,OAAO;AACvB,SAAK,YAAY;AACjB,QAAI,KAAK,UAAU;AACjB,WAAK,MAAM,SAAS,KAAK,SAAS;AAClC,uBAAiB,KAAK,QAAQ,iBAAiB,KAAK,SAAS,QAAQ;AACrE,WAAK,WAAW;AAAA,IAClB;AACA,SAAK,GAAG,UAAU,OAAO,WAAW;AACpC,UAAM,QAAQ;AAAA,EAChB;AAAA,EAEQ,iBAAiB;AACvB,QAAI,CAAC,KAAK,GAAG,UAAU,SAAS,QAAQ,KAAK,CAAC,KAAK,GAAG,UAAU,SAAS,OAAO,GAAG;AACjF;AAAA,IACF;AAQA,SAAK,YAAY,SAAS,cAAc,MAAM;AAC9C,SAAK,UAAU,aAAa,eAAe,MAAM;AACjD,SAAK,UAAU,MAAM,UACnB;AACF,SAAK,GAAG,sBAAsB,YAAY,KAAK,SAAS;AACxD,SAAK,YAAY,IAAI,qBAAqB,KAAK,YAAY;AAC3D,SAAK,UAAU,QAAQ,KAAK,SAAS;AAAA,EACvC;AAAA,EAeQ,eAAe;AACrB,SAAK,SAAS,KAAK,GAAG,cAAc,sBAAsB;AAC1D,QAAI,CAAC,KAAK,OAAQ;AAElB,UAAM,KAAK,KAAK,OAAO,aAAa,eAAe;AACnD,SAAK,QAAS,MAAM,MAAM,eAAe,KAAK,IAAI,EAAE,KAAM,KAAK,GAAG,cAAc,cAAc;AAC9F,QAAI,CAAC,KAAK,MAAO;AAEjB,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,SAAK,OAAO,iBAAiB,SAAS,KAAK,gBAAgB,EAAE,OAAO,CAAC;AACrE,SAAK,OAAO,iBAAiB,SAAS,KAAK,aAAa,EAAE,OAAO,CAAC;AAClE,SAAK,OAAO,iBAAiB,WAAW,KAAK,kBAAkB,EAAE,OAAO,CAAC;AAAA,EAC3E;AAwBF;AAvGa,OAkBJ,MAAM;",
6
+ "names": []
7
+ }
@@ -1,9 +1,9 @@
1
- import {
2
- Utils
3
- } from "./chunk-M372EDXD.mjs";
4
1
  import {
5
2
  Component
6
- } from "./chunk-PD6HYHAE.mjs";
3
+ } from "./chunk-EB2V4OKL.mjs";
4
+ import {
5
+ Utils
6
+ } from "./chunk-67UNY7RH.mjs";
7
7
 
8
8
  // src/ts/components/commandPalette.ts
9
9
  var _defaults = {
@@ -11,10 +11,16 @@ var _defaults = {
11
11
  closeOnRun: true
12
12
  };
13
13
  var APPLE = typeof navigator !== "undefined" && /Mac|iPhone|iPad|iPod/.test(navigator.platform);
14
+ var commandKey = (e) => APPLE ? e.metaKey && !e.ctrlKey : e.ctrlKey && !e.metaKey;
15
+ var isLetter = (e, letter) => e.key.toLowerCase() === letter || !/^[a-z]$/i.test(e.key) && /^[a-z]$/.test(letter) && e.code === `Key${letter.toUpperCase()}`;
16
+ var MOVE_KEYS = { ArrowDown: 1, ArrowUp: -1 };
14
17
  var fold = (text) => text.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase();
15
- var CommandPalette = class _CommandPalette extends Component {
18
+ var CommandPalette = class extends Component {
19
+ // HTMLElement, not HTMLDialogElement: init() takes the element type from
20
+ // here, and has always accepted any HTMLElement.
16
21
  constructor(el, options) {
17
- super(el, options, _CommandPalette);
22
+ const shortcut = el.dataset.shortcut;
23
+ super(el, { ...shortcut !== void 0 ? { shortcut: shortcut || null } : {}, ...options });
18
24
  this._active = null;
19
25
  this._generatedIds = [];
20
26
  /** Wires and refilters commands the page adds or removes later. */
@@ -29,14 +35,27 @@ var CommandPalette = class _CommandPalette extends Component {
29
35
  if (this.el.open) this.el.close();
30
36
  };
31
37
  this._handleInput = () => this._filter();
32
- this._handleKeydown = (e) => {
33
- if (e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP) {
38
+ this._handleKeydown = Utils.ignoringComposition((e) => {
39
+ const step = Utils.plainKey(e) ? MOVE_KEYS[e.key] : void 0;
40
+ if (step) {
34
41
  e.preventDefault();
35
- this._move(e.key === Utils.keys.ARROW_DOWN ? 1 : -1);
36
- } else if (e.key === Utils.keys.ENTER && !e.isComposing && e.keyCode !== 229 && this._active) {
42
+ this._move(step);
43
+ } else if (e.key === "Enter" && this._active) {
37
44
  e.preventDefault();
38
45
  this._run(this._active);
39
46
  }
47
+ });
48
+ /**
49
+ * The first Escape clears a typed query and the next closes the palette.
50
+ * Chromium and Firefox clear a search input on their own; WebKit closed at
51
+ * once, and so did every engine for a text input. Escape that cancels an
52
+ * IME composition is left to the IME.
53
+ */
54
+ this._handleEscape = (e) => {
55
+ if (e.key !== "Escape" || !this.input.value || Utils.isComposing(e)) return;
56
+ e.preventDefault();
57
+ this.input.value = "";
58
+ this.input.dispatchEvent(new Event("input", { bubbles: true }));
40
59
  };
41
60
  this._handleListClick = (e) => {
42
61
  const item = e.target.closest('[role="option"]');
@@ -64,23 +83,13 @@ var CommandPalette = class _CommandPalette extends Component {
64
83
  };
65
84
  this._handleShortcut = (e) => {
66
85
  const { shortcut } = this.options;
67
- if (!shortcut || e.defaultPrevented || e.altKey || e.shiftKey) return;
68
- if (!(APPLE ? e.metaKey && !e.ctrlKey : e.ctrlKey && !e.metaKey)) return;
69
- const letter = shortcut.toLowerCase();
70
- const latin = /^[a-z]$/i.test(e.key);
71
- const hit = e.key.toLowerCase() === letter || !latin && /^[a-z]$/.test(letter) && e.code === `Key${letter.toUpperCase()}`;
72
- if (!hit) return;
86
+ if (!shortcut || e.defaultPrevented || e.altKey || e.shiftKey || !commandKey(e)) return;
87
+ if (!isLetter(e, shortcut.toLowerCase())) return;
73
88
  e.preventDefault();
89
+ if (e.repeat) return;
74
90
  if (this.el.open) this.close();
75
91
  else this.open();
76
92
  };
77
- this.el["Expressive_CommandPalette"] = this;
78
- const shortcut = el.dataset.shortcut;
79
- this.options = {
80
- ..._CommandPalette.defaults,
81
- ...shortcut !== void 0 ? { shortcut: shortcut || null } : {},
82
- ...options
83
- };
84
93
  this.input = el.querySelector(":scope > input");
85
94
  this.list = el.querySelector(":scope > :is(ul, ol)");
86
95
  if (!this.input || !this.list) {
@@ -96,40 +105,25 @@ var CommandPalette = class _CommandPalette extends Component {
96
105
  attributes: true,
97
106
  attributeFilter: ["hidden", "disabled"]
98
107
  });
99
- this.input.addEventListener("input", this._handleInput);
100
- this.input.addEventListener("keydown", this._handleKeydown);
101
- this.list.addEventListener("click", this._handleListClick);
102
- this.list.addEventListener("pointermove", this._handlePointerMove);
103
- this.el.addEventListener("close", this._handleClose);
104
- document.addEventListener("keydown", this._handleShortcut);
108
+ const { signal } = this._events;
109
+ this.input.addEventListener("input", this._handleInput, { signal });
110
+ this.input.addEventListener("keydown", this._handleKeydown, { signal });
111
+ this.input.addEventListener("keydown", this._handleEscape, { signal });
112
+ this.list.addEventListener("click", this._handleListClick, { signal });
113
+ this.list.addEventListener("pointermove", this._handlePointerMove, { signal });
114
+ this.el.addEventListener("close", this._handleClose, { signal });
115
+ document.addEventListener("keydown", this._handleShortcut, { signal });
105
116
  }
106
117
  static get defaults() {
107
118
  return _defaults;
108
119
  }
109
- /**
110
- * Initializes instances of CommandPalette.
111
- * @param els HTML elements.
112
- * @param options Component options.
113
- */
114
- static init(els, options = {}) {
115
- return super.init(els, options, _CommandPalette);
116
- }
117
- static getInstance(el) {
118
- return el["Expressive_CommandPalette"];
119
- }
120
120
  /** If the palette is open. */
121
121
  get isOpen() {
122
122
  return this.el.open;
123
123
  }
124
124
  destroy() {
125
125
  this._observer?.disconnect();
126
- document.removeEventListener("keydown", this._handleShortcut);
127
- this.el.removeEventListener("close", this._handleClose);
128
126
  if (this.input && this.list) {
129
- this.input.removeEventListener("input", this._handleInput);
130
- this.input.removeEventListener("keydown", this._handleKeydown);
131
- this.list.removeEventListener("click", this._handleListClick);
132
- this.list.removeEventListener("pointermove", this._handlePointerMove);
133
127
  for (const name of ["role", "aria-controls", "aria-expanded", "aria-autocomplete", "aria-activedescendant"]) {
134
128
  this.input.removeAttribute(name);
135
129
  }
@@ -147,7 +141,7 @@ var CommandPalette = class _CommandPalette extends Component {
147
141
  const empty = this._empty();
148
142
  if (empty) empty.hidden = false;
149
143
  }
150
- this.el["Expressive_CommandPalette"] = void 0;
144
+ super.destroy();
151
145
  }
152
146
  _items() {
153
147
  return Array.from(this.list.children).filter(
@@ -255,8 +249,9 @@ var CommandPalette = class _CommandPalette extends Component {
255
249
  (this._action(item) ?? item).click();
256
250
  }
257
251
  };
252
+ CommandPalette.key = "Expressive_CommandPalette";
258
253
 
259
254
  export {
260
255
  CommandPalette
261
256
  };
262
- //# sourceMappingURL=chunk-UETTGDLI.mjs.map
257
+ //# sourceMappingURL=chunk-7X44MKEQ.mjs.map